如何通过产品ID关联React Native产品列表页与单品详情页?
解决React Native列表页跳转详情页并关联产品ID的问题
一、修正列表页的跳转逻辑
你当前的写法存在两处问题:路由名拼接ID的方式错误,且ItemView组件未接收navigation参数,导致无法调用navigate方法。
1. 给ItemView传入navigation参数
在渲染ItemView的父组件(比如FlatList的renderItem回调)中,需要把navigation传递进去:
<FlatList data={filteredDataSource} renderItem={({item}) => <ItemView item={item} navigation={navigation} />} keyExtractor={item => item.id.toString()} />
2. 正确传递产品参数到详情页
不要将ID拼在路由名里,而是通过navigate的第二个参数传递数据(可选择传递整个产品对象或仅ID):
const ItemView = ({ item, navigation }) => { return ( <View style={styles.itemStyle}> {/* 无需嵌套ScrollView,列表组件本身已支持滚动 */} <View style={styles.itenviewStyle}> <TouchableOpacity onPress={() => navigation.navigate('ProduitDescription', { productId: item.id, product: item // 直接传递整个产品对象,无需二次请求 })} > <Text>{item.id}</Text> <Text>{item.nom.toUpperCase()}</Text> <Text>{item.name.toUpperCase()}</Text> </TouchableOpacity> </View> </View> ); };
二、详情页接收并展示对应产品信息
1. 获取传递的参数并渲染
React Navigation 5+版本推荐使用route.params获取参数,直接渲染产品信息:
const ProduitDescription = ({ route, navigation }) => { // 取出传递的产品对象 const { product } = route.params; return ( <ScrollView> <View style={styles.header}> <View style={{marginLeft:40, marginTop:130}}> <Text style={{fontSize:25, fontWeight:'bold', marginTop:20}}>{product.name}</Text> <View style={{flexDirection:"row", marginTop:10}}> <Text>{product.adress}</Text> <Text style={{marginLeft:15, color:"green"}}>{product.description}</Text> </View> </View> </View> </ScrollView> ) }
(可选)若仅传递ID,详情页单独请求数据
如果只传递了productId,可在详情页重新发起请求获取单条产品数据:
import { useState, useEffect } from 'react'; const ProduitDescription = ({ route, navigation }) => { const [product, setProduct] = useState({}); const { productId } = route.params; useEffect(() => { fetch(`http://192.168.87.144:3000/medicaments/${productId}`) .then(res => res.json()) .then(data => setProduct(data)) .catch(err => console.error(err)); }, [productId]); return ( <ScrollView> <View style={styles.header}> <View style={{marginLeft:40, marginTop:130}}> <Text style={{fontSize:25, fontWeight:'bold', marginTop:20}}>{product.name}</Text> <View style={{flexDirection:"row", marginTop:10}}> <Text>{product.adress}</Text> <Text style={{marginLeft:15, color:"green"}}>{product.description}</Text> </View> </View> </View> </ScrollView> ) }
三、额外注意事项
- 确保路由配置中已注册
ProduitDescription页面:
<Stack.Navigator> <Stack.Screen name="ProductList" component={YourListScreen} /> <Stack.Screen name="ProduitDescription" component={ProduitDescription} /> </Stack.Navigator>
- 避免
ItemView中嵌套ScrollView,否则会引发滚动冲突问题。
内容的提问来源于stack exchange,提问作者Lino Lino
相关产品推荐
相关产品推荐

