为什么总是要求使用新的内部引用返回新对象

时间:2015-12-29 18:31:35

标签: javascript redux redux-framework

Redux要求总是从reducers返回新状态。例如,我有以下状态:

let initialState = {
   prop: 3,
   internalReferenceProp: {a:3}
}

修改internalReferenceProp的reducer。可以实现此缩减器仅更改state对象引用或同时更改stateinternalProperty

function(state=initialState, action) {
  // changing only state reference
  let newState = Object.assign({}, state);
  newState.internalReferenceProp.a = 7;
  return newState;

  // changing both state and internalReferenceProp reference
  return Object.assign({}, state, {internalReferenceProp: {a:7}})
}

由于我被告知第一种方法不正确,所以我的问题是,改变内部参考的要求背后的原因是什么?我理解我应该更改state引用,因为它允许轻松比较以检测state是否已更改,但为何更改内部引用?

1 个答案:

答案 0 :(得分:2)

第一个显然不正确,因为Object.assign执行浅拷贝,而不是深拷贝。

// changing only state reference
let newState = Object.assign({}, state);

newState === state // false
newState.internalReferenceProp === state.internalReferenceProp // true

state.internalReferenceProp.a // 3
newState.internalReferenceProp.a = 7 // 7
state.internalReferenceProp.a // 7

您可以通过这种方式看到,如果我们在newState中更改某些内容,它也会在state中更改。如果组件仅对internalReferenceProp感兴趣,这将使更改无法检测到。这也被称为“副作用”,这是一种不好的做法。

简而言之,如果您的输入(在这种情况下为state)以任何方式发生变化,则称其为副作用,并且在redux中出错。

以下是为什么这很糟糕的一个例子:

let data = getData(); // from redux

return (
  <ChildComponent someProp={data.internalReferenceProp} />
);

如果我们使用带有副作用的版本,ChildComponent将永远不会重新渲染,因为它的道具没有改变。 oldData.internalReferenceProp === newData.internalReferenceProp