Reactjs Redux:为什么对一级状态进行肤浅复制是一个错误?

Reactjs Redux:为什么对一级状态进行肤浅复制是一个错误?,reactjs,redux,react-redux,Reactjs,Redux,React Redux,在阅读关于在Redux中更新嵌套状态对象的文档时,我偶然发现了这一点,即仅对顶级对象进行浅拷贝是不够的: function updateNestedState(state, action) { // Problem: this only does a shallow copy! let newState = {...state}; // ERROR: nestedState is still the same object! newState.nestedSta

在阅读关于在Redux中更新嵌套状态对象的文档时,我偶然发现了这一点,即仅对顶级对象进行浅拷贝是不够的:

function updateNestedState(state, action) {
    // Problem: this only does a shallow copy!
    let newState = {...state};

    // ERROR: nestedState is still the same object!
    newState.nestedState.nestedField = action.data;

    return newState;
}
但我不知道为什么这还不够,因为从技术上讲,它是有效的,正如你在这把小提琴中看到的:

我很高兴能进一步澄清/解释此声明,也很高兴能举例说明更新此类状态对象的最佳实践


谢谢

假设您有这样一个状态对象:

let state = { a: { b: 1 } };

let cp = { ...state }

cp.a === state.a //true, that means that those are the exact same objects.
这是因为»内部«对象(
state.a
)通过引用添加到
cp
。如果您现在这样做:

cp.a.b = 10;
您也可以在
状态.a.b
中更改该值。所以这里的错误是:如果您想修改
state.a.b
,那么您必须用一个新对象替换它,具有如下的新值:

let cp = {
  ...state,
  a: {
     ...state.a.b
     b: 2
  }
}
原因是你被要求写纯函数,解释这个问题:

var a = { b: 1 };

//not a pure function
function foo (obj) {
  obj.b++;
  return obj;
}

for (var i = 0; i < 10; i++) foo(a);
//a.b = 11;

在这种情况下,
a
不会被修改,因此
条(a)
的输出将始终产生相同的输出。

假设您有这样一个状态对象:

let state = { a: { b: 1 } };

let cp = { ...state }

cp.a === state.a //true, that means that those are the exact same objects.
这是因为»内部«对象(
state.a
)通过引用添加到
cp
。如果您现在这样做:

cp.a.b = 10;
您也可以在
状态.a.b
中更改该值。所以这里的错误是:如果您想修改
state.a.b
,那么您必须用一个新对象替换它,具有如下的新值:

let cp = {
  ...state,
  a: {
     ...state.a.b
     b: 2
  }
}
原因是你被要求写纯函数,解释这个问题:

var a = { b: 1 };

//not a pure function
function foo (obj) {
  obj.b++;
  return obj;
}

for (var i = 0; i < 10; i++) foo(a);
//a.b = 11;

在这种情况下,
a
不会被修改,因此
bar(a)
的输出将始终产生相同的输出。

因为状态应该被复制,不允许修改。@DaveNewton,谢谢。问题是为什么这是不允许的。除了存在严重错误的风险外,我修改状态对象的方式对React的呈现机制是否有任何性能影响?因为React不是这样工作的(°u o)/,因为状态应该被复制,而修改是不允许的。@DaveNewton,谢谢。问题是为什么这是不允许的。除了存在严重错误的风险外,我修改状态对象的方式对React的呈现机制是否有任何性能影响?因为React不是这样工作的。谢谢除了存在严重错误的风险外,我修改状态对象的方式是否对React的呈现机制有任何性能影响?主要问题是,需要该状态的连接React组件可能会认为没有任何更改,而不会重新呈现。请参阅和。@GlennMohammad:不,任何时候如果不这样做,都有可能出现渲染错误。查看原始问题,假设一个
mapState
函数正在提取
state.nestedState
。这仍然是与以前相同的引用,因此组件将跳过重新渲染,因为它认为没有任何更改。是。请看我的帖子,在那里我特别谈到了。另外,请注意,默认情况下,这将在变异上引发错误。是的,因此,如果您使用我们的
createSlice
createReducer
函数,它应该主要消除reducer中的意外变异。假设在其他地方仍然有可能改变状态,或者如果您完全手工编写简化程序,那么我们有一个中间件来捕获这些错误。明白了。谢谢除了存在严重错误的风险外,我修改状态对象的方式是否对React的呈现机制有任何性能影响?主要问题是,需要该状态的连接React组件可能会认为没有任何更改,而不会重新呈现。请参阅和。@GlennMohammad:不,任何时候如果不这样做,都有可能出现渲染错误。查看原始问题,假设一个
mapState
函数正在提取
state.nestedState
。这仍然是与以前相同的引用,因此组件将跳过重新渲染,因为它认为没有任何更改。是。请看我的帖子,在那里我特别谈到了。另外,请注意,默认情况下,这将在变异上引发错误。是的,因此,如果您使用我们的
createSlice
createReducer
函数,它应该主要消除reducer中的意外变异。假设在其他地方仍然有可能改变状态,或者如果您完全手工编写约简,那么我们有一个中间件来捕获这些错误。