以下是Redux reducer的示例:
case REDUCE_ME:
const newState = state.setIn(['a', 'b', 'c'], payload);
payload.id = 'I MANIPULATE STORE!';
return newState; // newState.a.b.c.id is 'I MANIPULATE STORE!'
预期行为:id
不应更改。
感谢帮助者。
答案 0 :(得分:2)
所有这一点都是因为您的有效负载不是不可变对象。同样的事情与更少的背景:
const a = {'foo': 'bar};
您无法为a = 'baz';
之类的值重新分配值,因为a
是常量。但是您可以更改a.foo
的值,因为它不是常量/不可变的。您可以使用a.foo = 'baz';
,它会起作用。所以你用immutableJs做同样的事情。如果要拥有完全不可变结构,请将有效负载转换为不可变。并且您已更新了值,因为immutablejs包含指向源变量的指针,而不创建该值的新本地实例。
简而言之 - 在使用有效负载之前使用payload = Immutable.fromJS(payload)
,您可以将所有结构都视为不可变。
const state1 = new Immutable.fromJS({
a: {
b: {
c: 'foo'
}
}
});
console.log('State 1', state1.toJS());
let payload = 'bar';
const state2 = state1.setIn(['a','b','c'], payload);
console.log('state2 after 1st change',state2.toJS());
payload = 'baz';
console.log('state2 adter 2nd change',state2.toJS()); // c will be still bar
let payload2 = {'a': 'bar'};
// attaching payload2 which can not be changed from object to something else but it's inside values can be changed.
// same like with const a = {'foo': 'bar}; you cant re-assign value to a, but you can modify a.foo = 'whatever else';
const state3 = state1.setIn(['a','b','c'], payload2);
console.log('state3 after 1st change',state3.toJS());
payload2.a = 'baz';
console.log('state3 after 2nd change (switched to baz)',state3.toJS());
payload2 = 'baz';
console.log('state3 after 3rd change (tried to set payload2 to string)',state3.toJS());