[英]Unexpected behavior of Object.assign() in Immer in Redux
I'm using redux-starter-kit (which includes Immer library for mutable updates) and for some reason this reducer doesn't work: 我正在使用redux-starter-kit(包括Immer库用于可变更新),并且由于某种原因,这个reducer不起作用:
reInitializeState(state, action) {
state = Object.assign({}, initialState);
state.someProperty = true; // this does not get set
},
But this one does: 但是这个做了:
reInitializeState(state, action) {
Object.assign(state, initialState);
state.someProperty = true; // this does
},
I would expect them to do the same thing. 我希望他们能做同样的事情。 What is going on here?
这里发生了什么?
Reassigning a variable, by itself, will almost never have any effect elsewhere. 重新分配变量本身几乎不会在其他地方产生任何影响。 If you pass a variable as a parameter, then reassign that variable, and the function ends, nothing outside of the function will see any change.
如果将变量作为参数传递,然后重新分配该变量,并且函数结束,则函数外部的任何内容都不会发生任何变化。 Similarly:
同理:
let someVar = 'foo'; function reassign(str) { str = 'bar'; } reassign(someVar); console.log(someVar);
Reassigning inside the function above doesn't do anything, because the reassignment does not change what the outer binding of someVar
points to. 在上面的函数内部重新分配没有做任何事情,因为重新分配不会改变
someVar
的外部绑定指向的内容。
Your second snippet: 你的第二个片段:
reInitializeState(state, action) {
Object.assign(state, initialState);
state.someProperty = true; // this does
},
Here, you're mutating the original state
object that was passed as a parameter, so the change is seen outside the function. 在这里,您正在改变作为参数传递的原始
state
对象,因此可以在函数外部看到更改。 In the other snippet, you're mutating an entirely new object , an object which cannot be seen elsewhere in the script, and proceeds to get garbage collected. 在另一个片段中,你正在改变一个全新的对象 ,一个在脚本的其他地方无法看到的对象,并继续收集垃圾。
What you're doing here: 你在这做什么:
state = Object.assign({}, initialState);
Is copying initialState
into a new object, and discarding the contents of state
. 将
initialState
复制到新对象中,并丢弃state
的内容。 You should be assigning to state
not to {}
, and assigning the result to state
. 您应该将
state
分配给{}
,并将结果分配给state
。
state = Object.assign(state, initialState);
With Immer you mutate objects in-place for creating the next immutable copy. 使用Immer,您可以就地创建对象以创建下一个不可变副本。 In the first example, because
state
comes in as a param, doing: 在第一个例子中,因为
state
作为一个参数进入,所以:
state = Object.assign({}, initialState);
reassigns state
to a new object, so setting someProperty
on that new object doesn't cause any changes -- you have to mutate on the param itself. 将
state
重新分配给新对象,因此在该新对象上设置someProperty
不会导致任何更改 - 您必须在param本身上进行变异。
In the second example, you don't reassign state
to something else, so calling state.someProperty
and modifying it modifies the original state object. 在第二个示例中,您不会将
state
重新分配给其他内容,因此调用state.someProperty
并修改它会修改原始状态对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.