为什么要求始终返回具有新内部引用的新对象

Why is the requirement to always return new object with new internal references

本文关键字:新对象 引用 对象 新内部 返回 为什么      更新时间:2023-09-26

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

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

以及修改internalReferenceProp的减速器.这个化简器可以实现为仅更改对象引用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是否更改,但为什么要更改内部引用?

第一个显然是不正确的,因为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 .