如何在Redux Reducer中改变状态数组?

时间:2018-08-28 21:42:28

标签: javascript reactjs redux state reducers

更改前的状态如下:

foreignBases: [
  {
    base: {
      id: "5b8125ec14bb4f35f8f01aa9",
      ...
    },
    baseuser: {
      userId: "tester1",
      ...
    }
  },
  { base: { ... }, baseuser: { ... } }
]

通过分派用户将baseuser键中的布尔值更改为true,然后应该让reducer为该特定键值对更新状态,但是我似乎无法得到它正确与此:

for (let i = 0; i < state.foreignBases.length; i++) {
  if (action.baseUser.created === state.foreignBases[i].baseuser.created) {
    return Object.assign({}, state, {
      foreignBases: [
        ...state.foreignBases,
        {
          base: { ...state.foreignBases[i].base },
          baseuser: action.baseUser
        }
      ]
    });
}

当我真的只需要在一个对象中替换一个基本用户的布尔值时,这只会向状态添加另一个对象

1 个答案:

答案 0 :(得分:1)

请确保在下面检查更新。

spread运算符正在重新插入整个foreignBase,然后您添加了另一个我假设是您想要的突变的对象。

我在想你的意思是这样(未经测试)

for (let i = 0; i < state.foreignBases.length; i++) {
  if (action.baseUser.created === state.foreignBases[i].baseuser.created) {
    let foreignBases = [...state.foreignBases];
    foreignBases[i].baseuser = action.baseUser;
    return Object.assign({}, state, {foreignBases});
  }
}

更新 :@devserkan提醒我,散布运算符“不进行深层复制”,这在Redux中是不行的!所以我去寻找the updating an item in an array official pattern,我相信它是这样使用的(再次未经测试):

let foreignBases = state.foreignBases.map((foreignBase) => {
  if (action.baseUser.created === foreignBase.baseuser.created) {
    return {action.baseUser};
  } else {
    return foreignBase
  }
});
return Object.assign({}, state,  { 
   ...foreignBase,
   baseuser: action.baseUser
});

更新2 :注释中的@devserkan再次提供了宝贵的见解,这次,通过嵌套在状态对象的某些部分中,修复了原始的for循环。类似于突变。这种方法可以避免这种情况,并允许您仍然使用for循环。

for (let i = 0; i < state.foreignBases.length; i++) {
  if (action.baseUser.created === state.foreignBases[i].baseuser.created) {
    const newItem = {
      ...state.foreignBases[i],
      baseuser: action.baseUser
    };
    const newforeignBases = Object.assign([], state.foreignBases, {
      [i]: newItem
    });
    return Object.assign({}, state, { foreignBases: newforeignBases });
  }
}