React Native Category Tabs - setiap tab menampilkan kategori yang berbeda
Saat ini saya mencoba menerapkan layar penjelajahan, di mana pengguna dapat memilih kategori tertentu dari ScrollView yang menampilkan posting yang terkait dengan kategori itu.
Api saya mendapatkan semua data posting dari backend dan untuk setiap posting saya memiliki parameter call categoryId.
Yang saya coba lakukan adalah, misalnya jika salah satu kategori saya adalah olahraga. ketika pengguna memilih tab olahraga, daftar datar dengan semua posting tentang olahraga harus ditampilkan.
Dengan implementasi saat ini, saya memiliki tab kategori saya dan ketika saya memilih salah satu tab, semua posting tidak diberikan posting untuk kategori tertentu itu.
Ini kode saya:
function SearchScreen({ navigation }) {
const [posts, setPosts] = useState([]);
const [error, setError] = useState(false);
const [loading, setLoading] = useState(false);
const loadPosts = async () => {
setLoading(true);
const response = await postsApi.getPosts(page);
setLoading(false);
if (!response.ok) return setError(true);
setError(false);
setPosts(response.data);
};
const[page,setPage]=useState(0);
useEffect(() => {
loadPosts();
}, []);
const categories = [
{
label: "Sports",
id: 1,
},
{
label: "Fashion",
id: 2,
},
{
label: "News",
id: 3,
},
];
const[label,setLabel]=useState('Sports')
const[dataList,setDataList]=useState(posts)
const setLabelFilter=label=>{
setLabel(label)
}
return (
<>
<ActivityIndicator visible={loading} />
<Screen style={styles.screen}>
{error && (
<>
<View style={styles.error}>
<AppText>Could not retrieve posts from server.</AppText>
<AppButton title="Retry" onPress={loadPosts} />
</View>
</>
)}
<ScrollView
horizontal
style={{flexDirection:"row",
alignContent:"center",
width:Dimensions.get('window').width/1.05,
marginBottom:20,
}}
showsHorizontalScrollIndicator={false}
>
{categories.map(e=>(
<TouchableOpacity
style={[
{paddingHorizontal:10,paddingBottom:10},
label===e.label &&
{borderBottomWidth:3,
borderBottomColor:colors.primary,
borderRadius:2,
}
]}
onPress={()=>setLabelFilter(e.label)}
>
<AppText style={[{fontWeight:"500",color:colors.medium},label===e.label &&
{color:colors.primary,fontWeight:"700"}]}>{e.label}</AppText>
</TouchableOpacity>
))}
</ScrollView>
<FlatList
data={posts} // to have all the data
keyExtractor={(post) => post.id.toString()}
renderItem={({ item,index }) => (
<Card
title={item.title}
subTitle={item.subTitle}
onPress={() => navigation.navigate(routes.POST_DETAILS, {post:item,index})}
/>
)}
/>
</Screen>
</>
);
}
Ketika saya melakukan console.log (posts), berikut adalah tanggapan saya:
Object {
"Category": Object {
"id": 1,
"name": "Sports",
},
"categoryId": 3,
"createdAt": "2020-11-18T13:43:19.616Z",
"deletedAt": null,
"id": 506,
"subtTitle": "test",
"title": "test",
"updatedAt": "2020-11-23T06:57:44.150Z",
"userId": 1,
},
Saya telah berpikir untuk mengubah panggilan API saya untuk mendapatkan kategori berdasarkan idnya kemudian memasukkan semua posting untuk setiap kategori tertentu tetapi itu tidak berhasil, jadi saya pergi dengan panggilan API untuk mendapatkan semua posting.
Memperbarui
const[label,setLabel]=useState('Sports')
const setLabelFilter=label=>{
setLabel(label)
}
const [currentCategoryId, setCurrentCategoryId] = useState()
const toggleBrands = (categoryId) => {
setCurrentCategoryId(categoryId)
setLabel(label)
};
return(
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
>
{categories.map(e=>(
<TouchableOpacity
key={e.id}
onPress={()=>{toggleBrands(e.id),
setLabelFilter(e.label)}}
selected={e.id === currentCategoryId}
>
<AppText>{e.label}</AppText>
</TouchableOpacity>
))}
</ScrollView>
<FlatList
data={currentCategoryId ?
posts.filter(post=>post.categoryId===currentCategoryId
):posts}
Saya mencoba kode berikut dapatkah seseorang memberi tahu saya apakah itu benar atau tidak?
Jawaban
Sebagai contoh, katakanlah Anda pertama-tama akan mengklik sebuah item dalam Daftar Datar (menampilkan semua kategori) pada layar A, dan kemudian sistem akan dinavigasi ke layar B (dengan Daftar Datar yang menampilkan item dari kategori yang dipilih saja)
Metode normal adalah menampilkan secara dinamis hanya data dari kategori yang dipilih, misalnya dengan skrip php (untuk contoh ini, sjson.php)
Untuk layar A, akan seperti ini:
Layar Fungsi GetFlatListItem:
GetFlatListItem (fruit_name) {
this.props.navigation.navigate('ScreenB', {unitserial: fruit_name})
}
Layar A Flatlist bisa seperti ini:
data={ this.state.dataSource }
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={({item}) =>
<View style={{flex: 1, flexDirection: 'row', justifyContent:'flex-start'}}>
<Text onPress={this.GetFlatListItem.bind(this, item.serial)} >
{item.ok}</Text>
</View>
Untuk layar B akan seperti ini:
const enstring='https://www.test.com/sjson.php?serial=' + this.props.route.params.unitserial ;
return fetch(enstring)
.then((response) => response.json())
.then((responseJson) => {
this.setState({
dataSource: responseJson
}, function() {
// In this block you can do something with new state.
});
})
.catch((error) => {
console.error(error);
});
}
dan Flatlist bisa seperti:
<FlatList
data={ this.state.dataSource }
>
Harap dicatat bahwa Anda perlu mengubah kode Anda untuk menyesuaikan dengan kebutuhan Anda. Di atas hanyalah sebuah contoh.
Status Definisi Pertama:
const [apiRespPonse, setApiRespone] = useState("");
const [selectedTabData, setSelectedPost] = useState("");
const [category, setCategory] = useState("Sports");
Dalam panggilan api Anda, set The Response:
const fetchAllPost = () => {
setApiRespone([]);
const newArr = apiRespPonse.filter(obj => obj.label===category);
setSelectedPost(newArr)
};
Untuk opsi render Anda, gunakan filter untuk larik untuk mendapatkan data tab yang dipilih:
return (
<View style={styles.app}>
<View style={styles.header}>
<View style={{ flexDirection: "row" }}>
{categories.map((item, index) => {
return <Text onPress={()=>{
setCategory(categories[index])
const newArr = apiRespPonse.filter(obj => obj.label===category);
setSelectedPost(newArr)
}} style={styles.title}>{item.label}</Text>;
})}
</View>
</View>
<FlatList
data={selectedTabData}/>
</View>
);
};
Mungkin bisa membantu.
Jika saya mengerti benar, Anda hanya ingin menyegarkan konten daftar datar dengan kategori yang dipilih. Saya pikir kode yang Anda miliki sebelum pembaruan melakukan semua yang Anda butuhkan dengan sedikit pembaruan. Ini adalah bagian dari kode yang perlu Anda perbarui
{categories.map((e,index)=>(
<TouchableOpacity
...
style={[
...
index===page && {
borderBottomWidth:3,
borderBottomColor:colors.primary,
borderRadius:2,
}]
onPress={()=>{setPage(index)}}
>
...
</TouchableOpacity>
)}
Pastikan postsApi.getPosts(page);
mengembalikan data yang benar berdasarkan page
parameter yang diberikan .