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

如何在reducer中向嵌套对象添加新对象并解决状态被覆盖的问题

问题根因

你当前代码存在3个核心错误,直接导致状态被覆盖:

  • 大小写不匹配:初始状态属性是小写items,reducer里操作的是大写Items,属性不一致导致读取旧状态失效
  • 引用了不存在的状态属性:代码中state.exercises[action.grandParentId]无对应初始定义,读取永远返回undefined,每次展开都是空数组,自然相当于覆盖旧内容
  • 嵌套结构更新逻辑错误:你当前写法每次往grandParentId对应的数组里塞入仅包含当前idparent的新对象,没有对已存在的同idparent项做合并更新,旧的同idparent内容自然会被替换

修复后的ADD_ITEM分支代码

// ADD ITEM
case ADD_ITEM:
  // 取出当前grandParentId对应的数组,不存在则初始化为空
  const curGrandList = state.items[action.grandParentId] ?? [];
  // 查找数组中已存在的对应idparent项的位置
  const existParentIdx = curGrandList.findIndex(item => Object.hasOwn(item, action.idparent));
  
  let newGrandList;
  if (existParentIdx > -1) {
    // 已存在对应idparent,往其下的子数组追加新内容
    const existParent = curGrandList[existParentIdx];
    const updatedParent = {
      [action.idparent]: [
        ...existParent[action.idparent],
        {
          index: action.index,
          id: action.id,
          item: action.item,
        }
      ]
    };
    // 生成新的祖父级数组,替换对应位置的父项
    newGrandList = [
      ...curGrandList.slice(0, existParentIdx),
      updatedParent,
      ...curGrandList.slice(existParentIdx + 1)
    ];
  } else {
    // 不存在对应idparent,新增父项到数组末尾
    newGrandList = [
      ...curGrandList,
      {
        [action.idparent]: [
          {
            index: action.index,
            id: action.id,
            item: action.item,
          }
        ]
      }
    ];
  }

  return {
    ...state,
    items: {
      ...state.items,
      [action.grandParentId]: newGrandList
    }
  };

Reducer状态更新通用规范

  • 严格遵守不可变原则:所有更新都要返回全新的状态对象,不能直接修改原state的任何层级属性,普通对象/数组用展开运算符,复杂嵌套结构可以用immer库简化操作
  • 属性名完全对齐:大小写、拼写要和初始状态完全匹配,避免读取不到旧状态的问题
  • 层级更新由深到浅:嵌套结构更新要先修改最深层的属性,再逐层往上生成新的父对象/数组,避免浅拷贝导致深层引用依然指向原状态
  • 仅操作已定义字段:更新时只能操作初始状态中明确定义的合法字段,避免冗余数据和读取异常
  • 优先扁平化状态结构:多层嵌套的状态更新逻辑非常容易出错,推荐把嵌套数据扁平化为多个实体表,用id做关联,更新逻辑会大幅简化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 03:45:01