Redux中Immer中Object.assign()的异常行为

时间:2019-06-09 22:07:28

标签: javascript object redux

我正在使用redux-starter-kit(包括用于可变更新的Immer库),由于某种原因,该reducer无法正常工作:

reInitializeState(state, action) {
        state = Object.assign({}, initialState);
        state.someProperty = true; // this does not get set
    },

但是这个确实:

reInitializeState(state, action) {
        Object.assign(state, initialState);
        state.someProperty = true; // this does
    },

我希望他们做同样的事情。这是怎么回事?

3 个答案:

答案 0 :(得分:2)

重新分配变量本身几乎不会在其他地方产生任何影响。如果将变量作为参数传递,然后重新分配该变量,函数结束,则函数外部将看不到任何更改。同样:

let someVar = 'foo';
function reassign(str) {
  str = 'bar';
}
reassign(someVar);
console.log(someVar);

在上面的函数中重新分配不会执行任何操作,因为重新分配不会更改someVar的外部绑定所指向的内容。

您的第二个片段:

reInitializeState(state, action) {
    Object.assign(state, initialState);
    state.someProperty = true; // this does
},

在这里,您正在变异作为参数传递的原始state对象,因此更改可以在函数外部看到。在另一个代码段中,您正在变异一个完全新的对象,该对象在脚本的其他位置无法看到,并继续收集垃圾。

答案 1 :(得分:2)

您在这里做什么:

state = Object.assign({}, initialState);

正在将initialState复制到一个新对象中,并丢弃state的内容。您应该将state分配给{},而不是state

state = Object.assign(state, initialState);

答案 2 :(得分:1)

使用Immer,您可以在原处对对象进行突变以创建下一个不变的副本。在第一个示例中,由于state作为参数进入,因此:

state = Object.assign({}, initialState);

state重新分配给新对象,因此在该新对象上设置someProperty不会引起任何更改-您必须在参数本身上进行变异。

在第二个示例中,您没有将state重新分配给其他对象,因此调用state.someProperty并对其进行修改将修改原始状态对象。