Redux:为什么做一层状态的浅拷贝是错误的? [英] Redux: Why making a shallow copy of one level of the state is a mistake?
问题描述
在阅读有关在 Redux 中更新嵌套状态对象的文档时,我偶然发现了这个 常见错误,其中指出仅对顶层对象进行浅拷贝是不够的:
While reading the documentation about updating nested state object in Redux, I stumbled upon this common mistake, which states that doing a shallow copy of the top level object is not sufficient:
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;
}
但我不知道为什么它不够用,因为从技术上讲它是有效的,正如你在这个小提琴中看到的:https://codesandbox.io/s/D9l93OpDB
but I couldn't find out why it isn't sufficient, because technically it's working, As you can see in this fiddle: https://codesandbox.io/s/D9l93OpDB
我很乐意对此声明进行进一步的澄清/解释,也很乐意举例说明更新此类状态对象的最佳做法是什么.
I'll be happy for further clarification/explanation regarding this statement, and also will be happy for an example of what is the best practice of updating such state objects.
谢谢!
推荐答案
假设你有一个这样的状态对象:
Assume you have a state object like that:
let state = { a: { b: 1 } };
let cp = { ...state }
cp.a === state.a //true, that means that those are the exact same objects.
那是因为 »inner« 对象 (state.a
) 是通过引用添加到 cp
的.如果你现在这样做:
that is because the »inner« Object (state.a
) is added to cp
by reference. If you now do:
cp.a.b = 10;
您也在 state.a.b
中更改值.所以这里的错误是:如果你想修改 state.a.b
,那么你必须用一个新的对象替换它,有一个像这样的新值:
You change the value also in state.a.b
. So the mistake here is: if you want to modify state.a.b
, than you have to replace that with a new Object, having a new value like so:
let cp = {
...state,
a: {
...state.a.b
b: 2
}
}
这样做的原因是要求您编写»纯«函数,解释一下:
The reason for this is that you are asked to write »pure« functions, to explain consider this:
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;
所以每次调用foo(a)
都会修改对象,会产生不同的输出并修改一个全局变量.
So the object is modified each call of foo(a)
will produce different output and modify a global variable.
以上内容可能会导致您遇到非常讨厌的错误,这些错误很难找到并防止您遇到这种情况,请选择以下内容.
The above can lead you to really nasty bugs, which are hard to find and to prevent you from running into this prefer the below.
//a pure function
function bar (obj) {
return {
...obj,
b + 1
}
}
for (var i = 0; i < 10; i++) bar(a);
//a.b = 2
在那种情况下 a
没有被修改,所以 bar(a)
的输出将始终产生相同的输出.
In that case a
is not modified, so the output of bar(a)
will always yield the same output.
这篇关于Redux:为什么做一层状态的浅拷贝是错误的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!