我使用createSlice()
中的redux-starter-kit
。借助immer
可以简化化简器中的状态。但是他们说immer
中有一些限制。例如,您不应变异并同时从化简器返回新状态。所以我选择像这样变异
第一次尝试
const testSlice = createSlice({
initialState: 4,
reducers:{
increment: state => {state = state + 1},
decrement: state => {state = state - 1}
}});
但是此代码不起作用。特别是,当我调度crement()或decrement()时,我在Redux Dev Tools中看到了动作,但是状态保持不变。
好的。让我们像这样返回新状态:
第二次尝试
const testSlice = createSlice({
initialState: 4,
reducers:{
increment: state => state + 1,
decrement: state => state - 1
}});
并且此代码按预期工作。
毕竟,我已经尝试过这种构造了
第三次尝试
const testSlice = createSlice({
initialState: {counter:4},
reducers:{
increment: state => {state.counter = state.counter + 1},
decrement: state => {state.counter = state.counter - 1}
}});
这也有效 问题是-为什么第三个无效而同时第一个无效?
答案 0 :(得分:2)
第一个示例不起作用的原因是因为您没有改变状态-您只是将作为变量的变量 state
重新分配给化简器。在第三次尝试中,将状态用作对象。该对象将作为参数通过引用传递给您的化简器 ,因此您可以修改其属性。与redux无关,这是Javascript的工作方式。
答案 1 :(得分:0)
仅以示例的方式扩展Damnjan的出色答案,并注意在Javascript中不存在按引用传递ala C ++。 一切都是按价值传递的。
传递基元(字符串,数字,bigint,布尔值,未定义和符号)时,会将指针的副本分配给函数内部的局部变量。但是,当修改该值时,将创建一个新值,因为原语是自然界不可变的,并且本地指针“指向”了这个新的内存地址,而不是原始地址。
let test = { a: 0, b: 'foo', c: false };
function modifyPrimitives(a, b, c)
{
a = a + 1;
b = 'foo';
c = true;
}
modifyPrimitives(test.state);
console.log(test); // { a: 0, b: 'foo', c: false }
传递对象时,会发生同样的情况;该对象的指针的副本已分配给局部变量。您可以修改此对象的嵌套属性,但不能更改原始对象以指向另一个对象。您只有本地指针,您所能做的就是将其“重新指向”到新对象。
let test = { a: 0, b: 'foo', c: false };
function modifyObject(obj)
{
obj.a = obj.a + 1;
obj.b = 'foo';
obj.c = true;
obj = { wow: 'omgwtfbbq' }; // this won't change the object outside
}
modifyObject(test);
console.log(test); // {a: 1, b: "foo", c: true}