React.js 父子组件异步传值时子组件props未定义、data.map报错排查
React 父子组件传参报错解决方案
核心报错根因
- 你之前的初步判断存在偏差:首次渲染时data并不是undefined——父组件初始状态给
item设为空数组,首次渲染时item.slice(0,10)得到空数组,经过reduce聚合后返回的data是普通键值对对象(格式为{标题: 出现次数}),并非数组。只有数组才原生支持map方法,普通对象直接调用map就会触发TypeError: data.map is not a function报错。 - 附带的两个隐含bug:
- 子组件没有任何
return语句,React函数组件必须返回合法JSX结构,缺失返回值本身就会触发渲染异常 - 传参逻辑和子组件的使用逻辑完全错配:子组件预期用
map遍历数组,但实际收到的是聚合统计后的对象,二者数据结构不匹配
- 子组件没有任何
对应调整方案
根据你实际想要传递给子组件的数据类型,分两种场景调整即可:
场景1:子组件需要接收「截取后的10条照片原始列表」
此时你之前的传参内容写错了,不需要把reduce聚合后的对象传过去,直接把截取好的数组传给子组件:
// 父组件修改部分:替换传递给子组件的props <Switch> <Route path="/child" render={() => <Child data={slidedData} />} /> </Switch>
同时子组件增加类型兜底,补全返回逻辑:
const Child = ({ data }) => { // 兜底处理:如果收到的不是合法数组,就用空数组代替,避免map调用报错 const safeData = Array.isArray(data) ? data : []; const test = safeData.map(el => el); console.log(test); // 必须返回合法JSX结构,否则组件无法正常渲染 return <div>子组件渲染区域</div>; }
场景2:子组件需要接收「标题出现频次的统计结果」
此时保持父组件传对象的逻辑不变,修改子组件的遍历逻辑,不能直接对对象调用map,需要先把对象转成可遍历的数组:
const Child = ({ data }) => { // 兜底处理:如果收到的不是合法对象,就用空对象代替 const safeData = (typeof data === 'object' && data !== null) ? data : {}; // 用Object.entries把对象转成[key, value]格式的数组,再调用map遍历 const test = Object.entries(safeData).map(([title, count]) => ({ title, count })); console.log(test); return <div>子组件渲染区域</div>; }
日常开发优化小技巧:给跨组件传递的props增加默认兜底值,可以大幅减少空值、类型不对导致的报错。比如父组件传值时可以提前做兜底:
const safeData = data ?? {}; <Child data={safeData} />
内容的提问来源于stack exchange,提问作者kayak
相关产品推荐
相关产品推荐

