使用Javascript / Lodash替换Redux Store中对象数组中的对象

los*_*193 1 store object lodash reactjs redux

我在化简器中有一个对象数组,看起来像这样:

[
  {id:1, name:Mark, email:mark@email.com}, 
  {id:2, name:Paul, email:paul@gmail.com}, 
  {id:3,name:sally, email:sally@email.com} 
]
Run Code Online (Sandbox Code Playgroud)

以下是我的减速器。到目前为止,我可以currentPeople通过以下方法将新对象添加到reducer:

const INITIAL_STATE = { currentPeople:[]};

export default function(state = INITIAL_STATE, action) {
  switch (action.type) {
    case ADD_PERSON:
      return {...state, currentPeople: [ ...state.currentPeople, action.payload]}; 
  }
  return state;
}
Run Code Online (Sandbox Code Playgroud)

但是,这就是我被困住的地方。我可以使用lodash通过reducer更新一个人吗?如果我发送的动作有效载荷如下所示:

  {id:1, name:Eric, email:Eric@email.com}
Run Code Online (Sandbox Code Playgroud)

我可以用新字段替换ID为1的对象吗?

Ben*_*ger 6

是的,您可以按照自己的意愿绝对更新数组中的对象。而且,如果您不需要的话,也不需要更改数据结构。您可以将这样的情况添加到减速器中:

case UPDATE_PERSON: 
    return {
        ...state, 
        currentPeople: state.currentPeople.map(person => {
            if (person.id === action.payload.id) {
               return action.payload;
            }

            return person;
        }),
    };
Run Code Online (Sandbox Code Playgroud)

也可以使用隐式返回和三进制来缩短此时间:

case UPDATE_PERSON: 
    return {
        ...state, 
        currentPeople: state.currentPeople.map(person => (person.id === action.payload.id) ? action.payload : person),
    };
Run Code Online (Sandbox Code Playgroud)

Mihir关于使用normalizr将数据映射到对象的想法肯定是可行的,并且从技术上讲,使用参考更新用户而不是执行循环(在完成初始映射之后)会更快。但是,如果要保留数据结构,此方法将起作用。

同样,这样的映射只是更新对象的多种方法之一,并且需要浏览器支持Array.prototype.map()。您可以使用lodash indexOf()查找所需用户的索引(这很好,因为它在成功时会中断循环,而不是像.map那样继续执行),一旦有了索引,您就可以覆盖对象直接使用它的索引。但是请确保您不改变redux状态,如果您要像这样进行分配,则需要在克隆上进行操作clonedArray[foundIndex] = action.payload;