React Native点击列表项跳转详情页时出现props未定义错误
Undefined is not an object evaluating 'this.props.services.ser'错误 看起来你在点击列表项跳转详情视图时碰到了这个属性未定义的报错,我来帮你一步步排查解决:
1. 先确认Redux的mapStateToProps是否正确映射了services
你用了connect连接Redux Store,首先得检查你的mapStateToProps函数有没有把Store里的services数据正确映射到组件Props中。比如如果你的Reducer里的State结构是{ services: ... },那正确的映射应该是这样:
const mapStateToProps = (state) => { return { services: state.services // 这里的key要和Reducer里的State key完全对应 }; }; // 最后别忘了用connect连接你的组件 export default connect(mapStateToProps)(YourListItemComponent);
要是这里写错了key(比如写成state.service少了个s),那this.props.services就会是undefined,自然访问.ser就会报错。
2. 检查services的数据结构是否匹配你的访问方式
大概率你的services是一个数组(毕竟是ListView的数据源),而不是单个对象。如果是遍历数组渲染列表项,那你应该把单个service对象传递给详情组件,而不是直接访问this.props.services.ser。
举个正确的例子:
// 列表项组件里的renderRow函数 renderRow = (singleService) => { return ( <TouchableOpacity onPress={() => this.goToDetail(singleService)}> <Text>{singleService.ser}</Text> {/* 这里访问单个service的ser属性 */} </TouchableOpacity> ); }; // 跳转详情的方法,把单个service传过去 goToDetail = (service) => { this.props.navigation.navigate('DetailScreen', { targetService: service }); };
然后在详情组件里,要从路由参数里取传递过来的单个service,而不是从Props的services数组里找:
// 详情页组件 const DetailScreen = ({ route }) => { const { targetService } = route.params; return <Text>{targetService.ser}</Text>; };
如果services是数组,直接访问this.props.services.ser肯定会报错,因为数组本身没有ser这个属性。
3. 处理数据未加载的空值情况
如果你的services是异步获取的(比如从API请求数据),那组件初始渲染时,Store里的services可能还是undefined或者空数组。这时候要先做空值判断,避免报错:
render() { // 先判断services是否存在 if (!this.props.services) { return <Text>加载中...</Text>; } // 如果是数组,还要判断是否有数据 if (this.props.services.length === 0) { return <Text>暂无服务数据</Text>; } // 确认有数据后再渲染ListView return ( <ListView dataSource={this.props.services} renderRow={this.renderRow} /> ); }
也可以用ES6+的可选链操作符来安全访问属性,即使中间值是undefined也不会报错:
// 这样即使services或ser不存在,只会返回undefined,不会抛出错误 const serValue = this.props.services?.ser;
4. 检查Reducer是否初始化了services的初始状态
你的Reducer里要给services设置初始值(空数组或空对象),避免初始状态是undefined:
// reducers/Serv.js 你的Reducer文件 const initialState = { services: [] // 根据你的数据结构设置,比如单个对象就用{} }; const serviceReducer = (state = initialState, action) => { switch(action.type) { case 'FETCH_SERVICES_SUCCESS': return { ...state, services: action.payload }; default: return state; } }; export default serviceReducer;
如果没设置初始状态,Store里的services一开始就是undefined,组件Props里的services自然也是undefined,访问.ser就会触发报错。
内容的提问来源于stack exchange,提问作者Anjali

