为什么Reducer prev state与reactjs中的next状态相同?

时间:2018-02-18 07:59:50

标签: reactjs redux

在我staffReducer,我试图签署工作人员正在工作。 我有一个案例如下:

const staffReducer = (state=[], action)=>{
 switch(action.type){
  case "SET_WORKING":
   let staff = state.find(x=> x.id == action.id);
   if (!staff.working) {
    staff.working = true;
   }else{
    staff.working = false;
   }
  break;
 }
 return state;
}

此代码已被罚款但我在记录器中观察到loggerprev statenext state,我发现两个状态相同,但是以正确的方式,{{1} } working中的变量应为prev statefalse应为next state

现在两个处于两种状态的工作变量都是true

我的代码是错误的吗?

更新

组件代码如下:

true

1 个答案:

答案 0 :(得分:1)

Reducer是一个纯函数,与action一起返回一个新版本的state或默认情况下的相同状态。

在代码中,您正在对数组中的对象进行隐式更改,从而影响它在应用程序中立即链接到的每个引用。

所以要解决它:



const staffReducer = (state = [], action) => {
  switch (action.type) {
    case "SET_WORKING":
      return state.map((staff) => {
        if (action.id === staff.id) {
          return {
            ...staff,
            working: !staff.working
          }
        }
        return staff;
      })
    default:
      return state;
  }
}


// TO TEST the above
const initialState = [{
  id: 0,
  working: false
}, {
  id: 1,
  working: false
}, {
  id: 2,
  working: false
}]

console.log(initialState); // UNCHANGED

console.log(staffReducer(initialState, {
  type: "SET_WORKING",
  id: 2
})); // MODIFIED as expected




说明:

通过state.map我们返回一个新的数组副本,因此数组实例的标识不同,它已经破坏了对应用程序中先前版本的引用。

但就其自身而言还不够,因为你的更改在一个更深的层次上,在一个对象的数组项级别上,所以我们还必须确保数组中对象的身份是也可以通过使用object rest spread syntax这样来破坏与旧引用的连接 return { ...staff, working: !staff.working };

希望它有所帮助。