React Hooks 切换表格展示数据时持续触发map读取undefined报错
问题根因定位
TypeError: Cannot read property 'map' of undefined 报错由两处代码缺陷串联触发:
- 状态无初始兜底:定义
months状态时没有配置默认值,组件首次渲染阶段如果状态未完成初始化,直接调用map方法就会触发类型错误 - 事件回调参数错位:
handleChange自定义声明了countMonth、countYear两个入参,但React表单的onChange事件只会把事件对象作为唯一参数传给回调函数,这两个自定义参数在实际运行时永远是undefined;哪怕逻辑分支走到了setMonths的执行段,传入状态的也是未定义值,赋值后再次渲染时就会触发map遍历的报错。
分步修复方案
- 状态初始化加默认空数组兜底
定义months状态时直接用空数组作为初始值,从根源上避免首次渲染时值不存在的问题:// 替代原来无初始值的useState写法 const [months, setMonths] = useState([]) - 修正事件回调的参数传递逻辑
不要在事件回调的形参里硬塞需要传入的自定义数据,先把月度、年度的统计数据放到组件可访问的作用域内,在回调内部直接根据选中值匹配对应数据源赋值给状态,参考写法:
如果必须通过回调参数传入数据,绑定事件时需要用箭头函数显式传值,不能直接把函数引用挂到onChange属性上:// 假设monthlyStatData、yearlyStatData是提前获取到的两个维度统计数据 const handleChange = (e) => { const selectedValue = e.target.value if(selectedValue === 'months') { setMonths(monthlyStatData) } else if(selectedValue === 'year') { setMonths(yearlyStatData) } }// 显式把两个数据源作为参数传入回调 <select onChange={(e) => handleChange(e, monthlyStatData, yearlyStatData)}> - 渲染层加防御性兜底
考虑到异步加载数据的间隙状态可能出现空值,渲染时用可选链调用map方法,进一步降低运行时异常概率:<tbody> { months?.map(({ date, count }, index) => ( <tr key={index}> <td>{date}</td> <td>{count}</td> </tr> )) } </tbody>
内容的提问来源于stack exchange,提问作者Shuib Abdillahi
相关产品推荐
相关产品推荐

