为什么不能直接修改nestState?

时间:2017-01-09 05:14:25

标签: reactjs redux react-redux

redux docs我看到了:

  

常见错误#1:指向相同对象的新变量

     

定义新变量不会创建新的实际对象 - 它只会创建对同一对象的另一个引用。这个错误的一个例子是:

function updateNestedState(state, action) {
    let nestedState = state.nestedState;

    // ERROR: this directly modifies the existing object reference - don't do this!
    nestedState.nestedField = action.data;

    return {
        ...state,
        nestedState
    };
}
  

此函数正确返回顶级状态对象的浅表副本,但由于nestedState变量仍指向现有对象,因此状态直接发生变异。

但是我们知道combineReducers只是通过顶级参考判断状态变化。参见redux comBindReducer.js src

let hasChanged = false
const nextState = {}

for (let i = 0; i < finalReducerKeys.length; i++) {
  const key = finalReducerKeys[i]
  const reducer = finalReducers[key]
  const previousStateForKey = state[key]
  const nextStateForKey = reducer(previousStateForKey, action)

  if (typeof nextStateForKey === 'undefined') {
    const errorMessage = getUndefinedStateErrorMessage(key, action)
    throw new Error(errorMessage)
  }

  nextState[key] = nextStateForKey
  hasChanged = hasChanged || nextStateForKey !== previousStateForKey
}

return hasChanged ? nextState : state

它只访问每个reducer并判断状态引用是否发生了变化。

回到这个问题,修改了对象引用,因此hasChanged变量为true,而redux工作正常。所以我不知道状态的副作用是直接的?

如果你知道,请告诉我,谢谢。

1 个答案:

答案 0 :(得分:3)

我不认为该示例与cobmineReducers直接相关。我相信它试图提出与不变性相关的警告:每当复杂对象内的值发生变化时,整个层次结构都应该表明这一点。因此,如果state.nestedState.nestedField发生变化,则表示state.nestedState已发生变化,state也发生变化。只需查看statenestedState就可以了解nestedField已发生变化。
对这个概念不熟悉的开发人员可能经常认为将state.nestedState分配给新变量然后更改它很好,但事实并非如此,因为a === state.nestedState仍然是{ {1}}。

true只关心其中一个切片是否已更改。如果遵循上面的规则,它将会正常工作&#34;。但是,如果我们直接关注combineReducers会发生什么?参考文献仍然相同,因此不再适用。

说到React,connect以同样的方式工作。浅析比较道具,依赖于相同的规则:不需要深入比较,因为父母应该指出孩子是否已经改变。

回到你的问题:直接改变国家有什么副作用?
让我们使用你的例子:

state.nestedState

这样可以正常工作:

// reducer.js
function reducer(state, action) {
   let nestedState = state.nestedState;
   nestedState.nestedField = action.data;
   return {
       ...state,
       nestedState
   };
}

这不会:

connect(state => ({ state }))(MyComponent)

我希望它能回答你的问题,或者至少对它有所了解。