Redux 中不可变更新模式的问题

Issue with Immutable Update Pattern in Redux

我正在尝试更新 redux reducer 中的嵌套数组,这是我要更新的数组(只需添加 updating:true 提交)我的数组看起来像

我想添加一个 updating:true 在 number filed

之后对房间对象进行归档
items: Array(1)
    0:
    name: (2) [{…}, {…}]
    rooms: Array(2)
        0: {_id: "5d494e5b11b962065632c760", number: "100" …}
        1: {_id: "5d494e6211b962065632c761", number: "102" …}

长得像

items :
     [{
        name: [{}],
        rooms : [{}]
     }]

这是我的 redux reducer 代码,我正在尝试更新

case Constants.Status_ADD_REQUEST:
var ID = ID; // action id

return {...state,
  items:[{...state.items, 
        rooms:[{...state.items.rooms, 
            rooms:{...state.items.rooms.map(x=> x._id === ID ? {...x,updating: true} :  x )}}]
 }]
};

无论如何它不起作用:)请指导我更正它

再看看 spread Syntax in JavaScript, especially spread for array literals. For example in your reducer, you create a new state with an items array containing only one fix object (it would still be only one object, even if you would add more items in your example). This item object contains your previous converted and spread items arrayrooms 属性 - 不是真正的状态形状。

如何创建状态:

Full example repo (with TypeScript)

const initialState = {...}

function rootReducer(state = initialState, action) {
  switch (action.type) {
    case Constants.Status_ADD_REQUEST:
      return {
        ...state,
        items: state.items.map(item =>
          item.rooms.some(i => i.id === action.id)
            ? {
                ...item,
                rooms: item.rooms.map(room =>
                  room.id === action.id ? { ...room, updating: true } : room
                )
              }
            : item
        )
      };
    default:
      return state;
  }
}

采用 "Updating an Item in an Array" Redux docs 的风格。

如果您必须以这种方式手动确保immutable patterns,事情会很快变得糟糕。原因:更新嵌套数据的关键是每一层嵌套都必须适当地复制和更新(结构共享)。

为了避免这些问题,您的目标应该是 keep your state flattened and to compose reducers. If cloning your state still becomes too complex, you could make use of Immutable Update Utility Libraries. I personally can recommend immer,因为您可以以可变方式更改状态,而库通过 JavaScript 处理深度 clones/structural 共享透明代理。

PS:如果 "update room" 是您的 domain/app data.

的另一个名称,那么考虑另一个名称也可能有意义