简体   繁体   English

Redux中Immer中Object.assign()的意外行为

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM