在不改变状态的情况下,根据减少器中的给定索引更改嵌套数组值

Changing a nested array value based on a given index in a reducer while not mutating state

本文关键字:索引 数组 嵌套 状态 改变 情况下      更新时间:2023-09-26

我有一个使用数组的对象的reducer。我想根据给定的索引更改嵌套数组的值。这段代码可以工作,但我似乎无法使用深度冻结来进行测试。我试着看这里的redux示例http://redux.js.org/docs/basics/Reducers.html使用CCD_ 1来查找索引没有运气。有什么想法吗?

export default function myReducer(state = { toDisplay: [] }, action) {
  const { type, groupIndex, itemIndex } = action;
  const newObject = Object.assign({}, state);
  switch (type) {
    case actionTypes.TOGGLE_GROUP:
      newObject.toDisplay[groupIndex].isSelected = newObject.toDisplay[groupIndex].isSelected ? false : 'selected';
      return newObject;
    case actionTypes.TOGGLE_ITEM:
      newObject.toDisplay[groupIndex].values[itemIndex].isSelected = newObject.toDisplay[groupIndex].values[itemIndex].isSelected ? false : true;
      return newObject;
    default:
      return state;
  }
}

编辑:

对于任何好奇的人,在观看了一个有用的redux视频后,我想出了这个:

export default function myReducer(state = { toDisplay: [] }, action) {
  const { type, groupIndex, itemIndex } = action;
  switch (type) {
    case actionTypes.TOGGLE_GROUP:
      return {
        ...state,
        toDisplay: [
          ...state.toDisplay.slice(0, groupIndex),
          {
            ...state.toDisplay[groupIndex],
            isSelected: state.toDisplay[groupIndex].isSelected ? false : 'selected'
          },
          ...state.toDisplay.slice(groupIndex + 1)
        ]
      };
    case actionTypes.TOGGLE_ITEM:
      return {
        ...state,
        toDisplay: [
          ...state.toDisplay.slice(0, groupIndex),
          {
            ...state.toDisplay[groupIndex],
            values: [
              ...state.toDisplay[groupIndex].values.slice(0, itemIndex),
              {
                ...state.toDisplay[groupIndex].values[itemIndex],
                isSelected: state.toDisplay[groupIndex].values[itemIndex].isSelected ? false : true
              },
              ...state.toDisplay[groupIndex].values.slice(itemIndex + 1)
            ]
          },
          ...state.toDisplay.slice(groupIndex + 1)
        ]
      };
    default:
      return state;
  }
}

使用像建议的那样的助手/库可能是最好的途径,但我的团队不希望添加另一个依赖项。

首先,Object.assign(...)只执行浅层复制。请参见此处。

由于对象嵌套在对象内部的数组中,我强烈推荐react中的不变性助手(正如Rafael所提到的)。这些可以让你做这样的事情:

case actionTypes.TOGGLE_GROUP:
  return update(state, {
    toDisplay: {
      [groupIndex]: {
        isSelected: {$set: newObject.toDisplay[groupIndex].isSelected ? false : 'selected'}
      }
    }
  });

如果你想用原始js修改数组中的一个简单值,那么你可以使用这样的东西:

return list
  .slice(0,index)
  .concat([list[index] + 1])
  .concat(list.slice(index + 1));

(来源)