如何在redux中正确更新数组中的项目而不进行突变?

时间:2018-09-13 04:37:20

标签: javascript reactjs redux

const state = [
    {
        list: []
    }
];

列表是学生对象的列表,例如:

list: [
   { id: 1, name: "Mark", attendance: true },
   { id: 2, name: "John", attendance: false }
]

我有一个按钮,该按钮触发对API的发布请求,以将出勤率更改为true。发布请求返回已更改的学生对象,例如:

{ id: 2, name: "John", attendance: true }

这很好,如果没有错误,将分派ATTENDANCE_SUCCESS

现在,通过这种设置:

export function students(state, action) {
    let latestState = state[state.length - 1],
        newState = Object.assign({}, latestState);
    switch (action.type) {
       case "ATTENDANCE_SUCCESS":
          if (action.res.errorCode == 0) {
             // Need to change redux state 'attendance' value to true for a student with ID returned from the POST request
          }
    }

最初,我做了:

const studentChanged = newState.list.find(function(student) {
  return (
        student.id ===
        action.res.data.id
  );
});
studentChanged.attendance = true;

但是它改变了redux存储中的状态(尽管我不确定它是如何发生的,因为我认为newState已经是副本了。

正确的方法是什么?

1 个答案:

答案 0 :(得分:2)

以下内容将更新数组中的单个项目。这里的关键方面是,如果项目的id与操作有效负载中的id不匹配,它将返回未更改的项目,否则将更新attendance属性。 Array.prototype.map返回一个新数组,因此它将是不可变的。

export function students(state, action) {
  switch (action.type) {
    case "ATTENDANCE_SUCCESS":
      if (action.res.errorCode == 0) {
        return state.map(student => {
          // we want to leave non matching items unaltered
          if (student.id !== action.res.data.id) {
            return student;
          }

          return { ...student, attendance: true };
        });
      }

      return state;          
    default:
      return state;
  }
}

这里是StackBlitz来演示功能。

希望有帮助!