You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 状态的初始值设为数组 [],但后续存储的是收支差值数字,类型不匹配

修复方案

按以下步骤修改代码即可解决报错:

  1. filter 遍历前先对数组项做非空校验,再访问 type 属性
  2. 将 operations 拷贝逻辑移到 useEffect 内部,保证每次计算用的都是最新状态
  3. 修正 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 10:00:03