React Native项目报错:Cannot read property 'categoryId' of undefined 求助
问题排查:React Native跳转时Cannot read property 'categoryId' of undefined错误
开发Daily Fashion应用时,从HomeScreen跳转到ShowProductScreen时触发错误:Cannot read property 'categoryId' of undefined,错误定位到ShowProductScreen中的const category = route.params.categoryId代码行。尝试多种方案未解决,附上相关代码请求协助:
HomeScreen.js
import { View, Text, StyleSheet, Image, FlatList, TouchableOpacity, } from 'react-native'; import React from 'react'; import {imageSlider} from '../../data/Data'; import {SliderBox} from 'react-native-image-slider-box'; import {categoryList} from '../../data/Data'; const HomeScreen = props => { const {navigation} = props; return ( <View style={styles.mainContainer}> <SliderBox images={imageSlider} autoplay={true} circleLoop={true} sliderBoxHeight={250} /> <View style={styles.titleContainer}> <Text style={styles.text}>Categories</Text> </View> <FlatList data={categoryList} key={3} numColumns={3} keyExtractor={item => item.id} contentContainerStyle={styles.flatListContainer} showsVerticalScrollIndicator={false} renderItem={({item}) => { return ( <TouchableOpacity style={styles.button} onPress={() => navigation.navigate('ShowProduct', {categoryId: item.id}) }> <Image source={{uri: item.icon}} style={styles.icon} /> <Text style={styles.itemName}>{item.name}</Text> </TouchableOpacity> ); }} /> </View> ); }; const styles = StyleSheet.create({ mainContainer: { backgroundColor: 'white', flex: 1, }, titleContainer: { marginTop: 16, alignItems: 'center', }, text: { fontSize: 18, fontWeight: 'bold', color: 'black', }, flatListContainer: { padding: 8, }, button: { flex: 1, margin: 8, borderWidth: 1, borderColor: '#7CAF58', borderRadius: 10, height: 130, justifyContent: 'center', alignItems: 'center', }, icon: { width: 100, height: 100, resizeMode: 'contain', }, itemName: { color: 'black', }, }); export default HomeScreen;
ShowProductScreen.js
import { StyleSheet, Text, View, FlatList, Image, TextInput, TouchableOpacity, } from 'react-native'; import {Icon} from 'react-native-elements'; import React, {useEffect, useState} from 'react'; import realm from '../../store/realm'; const ShowProductScreen = props => { const {route} = props; const category = route.params.categoryId; const [data, setData] = useState([]); const collectData = () => { const allData = realm.objects('Product').filtered(`category = ${category}`); setData(allData); }; useEffect(() => { const productPage = navigation.addListener('focus', () => { collectData(); }); return productPage; }, []); return ( <View style={styles.mainContainer}> <FlatList data={data} contentContainerStyle={styles.flatListContainer} keyExtractor={item => item.id} renderItem={({item}) => { return ( <TouchableOpacity style={styles.itemButton}> <View style={styles.productContainer}> <Image style={styles.image} source={{uri: item.imagePath}} /> <View style={styles.textContainer}> <Text style={styles.title}>{item.productName}</Text> <Text style={styles.text}>{item.description}</Text> <Text style={styles.text}>$ {item.price}</Text> </View> </View> <TouchableOpacity> <Icon name="shoppingcart" type="antdesign" size={30} /> </TouchableOpacity> </TouchableOpacity> ); }} /> </View> ); }; export default ShowProductScreen; const styles = StyleSheet.create({ mainContainer: { flex: 1, backgroundColor: 'white', }, flatListContainer: { padding: 8, }, itemButton: { margin: 8, padding: 16, borderColor: '#7CAF58', borderWidth: 1, borderRadius: 10, flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', }, productContainer: { flex: 1, flexDirection: 'row', }, image: { width: 100, height: 100, }, textContainer: { flex: 1, marginLeft: 16, justifyContent: 'center', }, title: { color: 'black', fontSize: 18, fontWeight: 'bold', }, text: { color: 'black', fontSize: 16, }, });
解决方案
1. 修复参数读取与未定义处理
ShowProductScreen存在两个问题:未解构navigation导致useEffect中报错,以及未处理route.params为undefined的情况。修改代码如下:
const ShowProductScreen = props => { const { route, navigation } = props; // 解构navigation const category = route.params?.categoryId; // 使用可选链避免params为undefined时报错 const [data, setData] = useState([]); const collectData = () => { if (!category) return; // 无有效分类ID时终止查询 const allData = realm.objects('Product').filtered(`category = ${category}`); setData(allData); }; useEffect(() => { const productPage = navigation.addListener('focus', () => { collectData(); }); return productPage; }, [category]); // 添加category为依赖,参数变化时重新执行查询 // 无分类ID时显示提示 if (!category) { return ( <View style={styles.mainContainer}> <Text style={{ textAlign: 'center', marginTop: 20, fontSize: 16 }}>请从分类页面进入商品列表</Text> </View> ); } return ( // 原返回内容保持不变 ); };
2. 检查导航栈配置
确认导航栈中注册的页面名称为ShowProduct,与HomeScreen中navigation.navigate('ShowProduct')的名称完全一致,名称不匹配会导致参数无法传递。
3. 修正FlatList的key属性
HomeScreen中的FlatList使用key={3}是错误用法,直接移除该属性即可,keyExtractor已经能保证每个item的key唯一:
<FlatList data={categoryList} // 移除key={3} numColumns={3} keyExtractor={item => item.id} // 其他属性保持不变 />
内容的提问来源于stack exchange,提问作者Eric Leonardo
相关产品推荐
相关产品推荐

