Javascript Immutable.js允许对象的变异
下面是一个Redux reducer示例:Javascript Immutable.js允许对象的变异,javascript,immutable.js,Javascript,Immutable.js,下面是一个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不应更改 多亏了帮助者。所有这一切都是因为您的有效负载不是不可变的对象。同样的事情,
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
不应更改
多亏了帮助者。所有这一切都是因为您的有效负载不是不可变的对象。同样的事情,没有太多的背景:
const a = {'foo': 'bar};
不能将值重新分配给likea='baz'因为a
是一个常数。但是您可以更改a.foo
的值,因为它不是常量/不可变的。您可以使用a.foo='baz'代码>和它将工作。因此,您正在对immutableJs执行相同的操作。如果您想拥有完整的不可变结构,请将负载也转换为不可变。您已经更新了值,因为immutablejs持有指向源变量的指针,而不创建该值的新本地实例
简言之,在使用有效载荷之前,先使用payload=Immutable.fromJS(有效载荷)
,这样所有结构都是不可变的
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());
所有这一切都是因为您的负载不是不可变的对象。同样的事情,没有太多的背景:
const a = {'foo': 'bar};
不能将值重新分配给likea='baz'因为a
是一个常数。但是您可以更改a.foo
的值,因为它不是常量/不可变的。您可以使用a.foo='baz'代码>和它将工作。因此,您正在对immutableJs执行相同的操作。如果您想拥有完整的不可变结构,请将负载也转换为不可变。您已经更新了值,因为immutablejs持有指向源变量的指针,而不创建该值的新本地实例
简言之,在使用有效载荷之前,先使用payload=Immutable.fromJS(有效载荷)
,这样所有结构都是不可变的
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());
您对“不可能”的评论是什么意思?有效负载只是一个普通变量,它不会因为您使用它初始化不可变的东西而变得不可变。@tevemadar注释令人困惑。我的意思是它不应该影响newState。你对“不可能”的评论是什么意思?有效负载只是一个普通变量,它不会因为您使用它初始化不可变的东西而变得不可变。@tevemadar注释令人困惑。我的意思是它不应该影响newState。这和问题中的代码不太一样。。。负载显然是一个具有id属性的对象,OP是changingtanks@LukasLiesis,这很有意义。我必须补充一点,当对“state.merge(payload)”执行相同操作,然后尝试更改有效负载时,这不会更改存储。这与问题中的代码不太一样。。。负载显然是一个具有id属性的对象,OP是changingtanks@LukasLiesis,这很有意义。我必须补充一点,当对“state.merge(payload)”执行相同操作,然后尝试更改有效负载时,这不会更改存储。