简体   繁体   English

如何在 redux reducer 中改变数组的状态?

[英]How to mutate a array on state in a redux reducer?

State prior to change looks like this:更改前的状态如下所示:

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

via dispatch the user changes a boolean in the baseuser key to true , the reducer is then supposed to update the state for this particular key value pair, but I can't seem to get it right with this:通过 dispatch 用户将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
        }
      ]
    });
}

This just adds another object to the state, when I really just need to replace one boolean of baseuser in one object这只是将另一个对象添加到状态,当我真的只需要在一个对象中替换一个 baseuser 的布尔值时

Be sure to check below for updates.请务必检查以下更新。

The spread operator is re-inserting the entire foreignBases, and then you're adding another object with what I assume is your intended mutation.扩展运算符重新插入整个foreignBases,然后您添加另一个对象,我认为这是您想要的突变。

I'm thinking you mean something like this (untested)我想你的意思是这样的(未经测试)

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});
  }
}

Update : @devserkan reminded me that the spread operator "does not do a deep copy", which is a no-no in Redux!更新:@devserkan 提醒我,扩展运算符“不进行深度复制”,这是 Redux 中的禁忌! So I went looking for the updating an item in an array official pattern , which I believe is applied like this (again, untested):所以我去寻找更新数组官方模式中的一个项目,我相信它是这样应用的(再次,未经测试):

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
});

Update 2 : @devserkan in the comments again contributes valuable insight, this time fixing the original for loop, by nesting in parts of the state object.更新 2 :评论中的 @devserkan 再次提供了宝贵的见解,这次通过嵌套在状态对象的部分中来修复原始 for 循环。 Which is similar to mutation.这类似于突变。 This approach avoids that and allows you to still use a for loop.这种方法避免了这种情况,并允许您仍然使用 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 });
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM