React Native如何实现FlatList点击后仅展示选中玩具的详情?
问题
我有一个玩具数据库(Database.js),每个玩具包含8项信息(name、image、id、type、seller、短描述、长描述)。在ViewToys.js页面的玩具卡片列表中,每张卡片展示其中5项信息。当前点击卡片会跳转到SlugProduct.js页面,但该页面会显示数据库中所有玩具的信息,而非选中玩具的全部8项详情。
是否可以调整代码实现仅展示选中项的详情?我已使用keyExtractor(item.id),能否让React Native在点击玩具时,加载并展示对应id的详情?或是用其他方法?我觉得可以用useState实现,但不知具体操作。
我需要实现组件间的数据传递,以下是相关组件代码:
原FLToyCard组件代码
import { StyleSheet, Text, View, FlatList } from 'react-native' import React, {useState} from 'react' import Toy from './Database' import ToyCard from './ToyCard' const FLToyCard = ({navigation}) => { const [selectedToy, setSelectedToy] = useState(null) const headerComp = () => { return( <View style={{alignSelf: 'center'}}> <Text style={{fontSize: 25, padding: 10}}>All Toys For Sale</Text> </View> ) } const renderMyItem = ({item}) => { return( <View style={{flex: 1}}> <ToyCard name={item.name} image={item.image} price={item.price} desc={item.desc} seller={item.seller} value={selectedToy} onPress={()=>navigation.navigate('SlugProduct')} /> </View> ) } return( <View> <FlatList data={Toy} renderItem={renderMyItem} keyExtractor={(item)=>item.id} numColumns={2} ListHeaderComponent={headerComp} /> </View> ) } export default FLToyCard
原SlugFormat组件代码
import { StyleSheet, Text, View, ScrollView, Image, Button, TouchableOpacity } from 'react-native' import React, { useState, useEffect, useRoute } from 'react' import { AntDesign } from '@expo/vector-icons' const SlugFormat = ({name, seller, image, id, type, longDesc, price}) => { const [quantity, setQuantity] = useState(1); const addQuantity = () => { setQuantity(quantity + 1); }; const minusQuantity = () => { if (quantity !== 1){ setQuantity(quantity - 1); } }; return ( <ScrollView style={{backgroundColor: '#ffce20', height: '100%'}}> <Image style={styles.toyImage} source={image} /> <View> <View style={{flexDirection: 'row', justifyContent: 'space-between'}}> <Text style={styles.title}>{name} (#{id})</Text> <Text style={styles.price}>${price}</Text> </View> <View styles={{flexDirection: 'column'}}> <Text style={styles.links}>Seller: {seller}</Text> <Text style={styles.links}>Type: {type}</Text> </View> <Text style={styles.descriptionHeader}>Description</Text> <Text style={styles.description}>{longDesc}</Text> </View> <View> <View> <Text>Quantity: </Text> <View style={styles.quantityFrame}> <TouchableOpacity onPress={minusQuantity}> <AntDesign name="minuscircleo" size={35} color="black" /> </TouchableOpacity> <Text value={quantity} onChangeText={setQuantity} style={styles.quantity}>{quantity}</Text> <TouchableOpacity onPress={addQuantity}> <AntDesign name="pluscircleo" size={35} color="black" /> </TouchableOpacity> </View> </View> <Button title='Add To Cart'/> </View> </ScrollView> ) } export default SlugFormat
解决方案
核心是通过导航传递选中玩具的标识(ID或完整对象),在详情页匹配对应数据后渲染。以下是具体实现步骤:
步骤1:修改FLToyCard,跳转时传递选中玩具的ID
在navigation.navigate的第二个参数中,传入当前玩具的ID,这样详情页就能知道要展示哪一个玩具:
import { StyleSheet, Text, View, FlatList } from 'react-native' import React from 'react' import Toy from './Database' import ToyCard from './ToyCard' const FLToyCard = ({navigation}) => { const headerComp = () => { return( <View style={{alignSelf: 'center'}}> <Text style={{fontSize: 25, padding: 10}}>All Toys For Sale</Text> </View> ) } const renderMyItem = ({item}) => { return( <View style={{flex: 1}}> <ToyCard name={item.name} image={item.image} price={item.price} desc={item.desc} seller={item.seller} onPress={()=>navigation.navigate('SlugProduct', { toyId: item.id })} // 传递玩具ID /> </View> ) } return( <View> <FlatList data={Toy} renderItem={renderMyItem} keyExtractor={(item)=>item.id} numColumns={2} ListHeaderComponent={headerComp} /> </View> ) } export default FLToyCard
注:如果玩具数据量小,也可以直接传递完整的
item对象,比如navigation.navigate('SlugProduct', { toy: item }),这样详情页无需再从数据库查询。
步骤2:完善SlugProduct页面,匹配并传递选中玩具数据
在SlugProduct.js中,通过useRoute获取传递的参数,从数据库找到对应玩具,再把数据传给SlugFormat组件:
import React from 'react' import { View } from 'react-native' import SlugFormat from './SlugFormat' import Toy from './Database' import { useRoute } from '@react-navigation/native' const SlugProduct = () => { const route = useRoute() const { toyId } = route.params // 获取传递的玩具ID // 从数据库匹配对应ID的玩具 const selectedToy = Toy.find(toy => toy.id === toyId) return ( <View style={{flex:1}}> {/* 确保找到数据后再渲染组件 */} {selectedToy && <SlugFormat name={selectedToy.name} seller={selectedToy.seller} image={selectedToy.image} id={selectedToy.id} type={selectedToy.type} longDesc={selectedToy.longDesc} price={selectedToy.price} />} </View> ) } export default SlugProduct
如果选择直接传递完整玩具对象,SlugProduct可以简化为:
import React from 'react' import { View } from 'react-native' import SlugFormat from './SlugFormat' import { useRoute } from '@react-navigation/native' const SlugProduct = () => { const route = useRoute() const { toy } = route.params // 获取完整玩具对象 return ( <View style={{flex:1}}> {toy && <SlugFormat name={toy.name} seller={toy.seller} image={toy.image} id={toy.id} type={toy.type} longDesc={toy.longDesc} price={toy.price} />} </View> ) } export default SlugProduct
步骤3:SlugFormat组件无需修改
你的SlugFormat已经通过props接收所有需要的字段,保持原样即可。
内容的提问来源于stack exchange,提问作者paparonnie
相关产品推荐
相关产品推荐

