1

Redux では、リデューサーから常に新しい状態を返す必要があります。たとえば、次の状態があります。

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

そして、を変更するレデューサーinternalReferencePropstateこのレデューサーは、オブジェクト参照のみ、または両方stateを変更するために実装できますinternalProperty

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が、なぜ内部参照を変更するのですか?

4

1 に答える 1

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.

于 2015-12-29T20:58:55.937 に答える