React预算应用Balance组件报错Cannot read properties of undefined (reading 'type')
问题原因排查
- 核心报错来源:
operations数组中存在undefined项,你在filter回调中直接访问oneOperation.type时,遇到空项就会触发「读取undefined的type属性」的类型错误 - 日志打印4次的原因:React 18 开发环境默认开启严格模式,组件会额外重复渲染一次,如果你的
operations状态有2次更新(初始空数组、异步获取数据后赋值),叠加严格模式的重复渲染,刚好输出4次日志,不属于逻辑异常 - 隐性问题1:你在组件顶层声明
operationsListCopy拷贝,而非在useEffect内部获取最新状态,容易触发闭包陷阱导致计算结果不符合预期 - 隐性问题2:
total状态的初始值设为数组[],但后续存储的是收支差值数字,类型不匹配
修复方案
按以下步骤修改代码即可解决报错:
filter遍历前先对数组项做非空校验,再访问type属性- 将
operations拷贝逻辑移到useEffect内部,保证每次计算用的都是最新状态 - 修正
total状态的初始值为数字类型,避免后续类型报错
修复后代码参考:
export default function Balance(){ const operations = useSelector((state) => state.operations); console.log(operations); // 修正初始值为数字类型 const [total, setTotal] = React.useState(0); React.useEffect(() => { // 拷贝逻辑移到effect内部,获取最新的operations const operationsListCopy = [...operations]; // 先做非空校验,再判断type属性 let entryArray = operationsListCopy.filter((oneOperation) => oneOperation?.type === 'INCOME'); let entryArrayTotal = entryArray.reduce((amount, item) => item.amount + amount, 0); let exitArray = operationsListCopy.filter((oneOperation) => oneOperation?.type === 'EXPENSE'); let exitArrayTotal = exitArray.reduce((amount, item) => item.amount + amount, 0); let arrayTotal = entryArrayTotal - exitArrayTotal; setTotal(arrayTotal); }, [operations]); // 原有组件渲染逻辑 }
如果修改后仍有报错,建议检查 reducer 中修改 operations 状态的逻辑,确认是否存在往数组中插入 undefined 值的情况(比如错误读取了不存在的 action.payload 字段)。
内容的提问来源于stack exchange,提问作者Ignacio Garcia
相关产品推荐
相关产品推荐

