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

React调用数组设置函数时出现Cannot read properties of undefined (reading 'push')错误

问题:Gatsby构建后处理JSON的React状态更新触发Cannot read properties of undefined (reading 'push')错误

我在处理一个接收JSON文件的函数时遇到问题,该函数会根据键名执行特定逻辑,相关代码如下:

Object.entries(objJson).forEach(([key, val]) => {
  // eslint-disable-next-line no-param-reassign
  val = unConvertJSON(val)
  if (key.startsWith('item1')) {
    const index = parseInt(key.charAt(key.length - 1), 10)
    setItem1(prevArray => {
      const newItemArray = prevArray.slice()
      if (Array.isArray(newItemArray)) {
        newItemArray[index - 1].push(key)
        newItemArray[index - 1].sort()
        return newItemArray
      }
    })
    // ... 其他逻辑
  }
})

已通过Array.isArray(newItemArray)确认外层是数组,但仍出现以下错误:

TypeError: Cannot read properties of undefined (reading 'push')
    at networking.js:137:37
    at Po (react-dom.production.min.js:169:46)
    at Fo (react-dom.production.min.js:170:451)
    at Object.useState (react-dom.production.min.js:186:528)
    at t.useState (react.production.min.js:25:394)

使用Gatsby框架时,gatsby develop模式下函数正常运行,但执行gatsby build再gatsby serve测试构建包时会触发错误,导致页面空白,需要解决方案。


解决方案
  • 确保目标索引位置的元素是有效数组
    外层数组存在不代表newItemArray[index - 1]一定是数组或存在。在调用push前先检查并初始化:

    if (Array.isArray(newItemArray)) {
      // 初始化目标位置为空数组(如果不存在或不是数组)
      if (!Array.isArray(newItemArray[index - 1])) {
        newItemArray[index - 1] = []
      }
      newItemArray[index - 1].push(key)
      newItemArray[index - 1].sort()
      return newItemArray
    }
    
  • 校验索引的合法性
    键名结尾可能不是有效数字,导致index为NaN,进而index-1为无效索引。添加索引校验:

    const index = parseInt(key.charAt(key.length - 1), 10)
    // 跳过无效索引的处理
    if (isNaN(index) || index < 1) {
      return prevArray
    }
    
  • 统一SSR/SSG与客户端的初始状态
    Gatsby构建时会执行SSR/SSG,初始状态可能和开发模式不一致。确保item1的初始状态结构完整:

    // 示例:初始化一个长度为N的数组,每个元素都是空数组
    const [item1, setItem1] = useState(() => Array(5).fill([]))
    
  • 状态更新函数始终返回有效值
    当前代码中若newItemArray不是数组,会无返回值导致状态异常。补充默认返回逻辑:

    setItem1(prevArray => {
      const newItemArray = prevArray.slice()
      if (Array.isArray(newItemArray)) {
        // ... 处理逻辑
        return newItemArray
      }
      // 兜底返回原状态或空数组
      return prevArray || []
    })
    

内容的提问来源于stack exchange,提问作者Adawg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 14:35:56