如何在 ES5 Redux reducer 中初始化默认数据?
How to initialize default data in ES5 Redux reducer?
目前我还不能使用 ES6/ES2015,而且我坚持使用 ES5 来编写 Redux reducers。由于 reducer 的状态参数必须是不可变的,即使它是未定义的,我想出了以下模式:
function myState( state, action ) {
if ( typeof state === 'undefined' ) {
return myState( { value1: 'foo', value2: 'bar' }, action );
}
// actual state calculation here
}
关于如何使用 ES5 确保默认值的任何替代建议或意见?
编辑: 经过一些问题和建议:我进行递归调用的原因是我非常重视 "state is immutable"。因此,即使 state
参数为 undefined
,我也不会更改参数变量本身。我是不是把不变性看得太过分了?
另一种选择是这样的:
var initialState = { value1: 'foo', value2: 'bar' };
function myState( state, action ) {
state = state || initialState;
// actual state calculation here
}
Redux 不会强制你使用默认的参数语法。它只关心当它给你 undefined
作为状态时,你 return 其他东西,以便你的应用程序能够使用初始状态树启动。
ES6 中的这个函数:
function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state + 1
default:
return state
}
}
相当于ES5中的这个函数:
function counter(state, action) {
if (state === undefined) {
state = 0
}
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state + 1
default:
return state
}
}
验证这一点的一个好方法是run this code through the Babel REPL。
The reason I do a recursive call is that I take the "state is immutable" very seriously. So even when the state parameter is undefined, I don't change the parameter variable itself.
这里不需要递归调用。我认为您的问题可能包含一些关于 突变和引用分配之间差异的混淆。
写的时候
var x = { lol: true }
x.lol = false
你正在变异 x
对象。这是 Redux 所不允许的。
但是当你写
var x = { lol: true }
x = { lol: false }
原始对象保持完整。 x
“绑定”(也称为“变量”)刚刚开始指向另一个对象。
Redux 不关心你是否更改了 state
参数所指的内容。它在您的函数中是本地的。不管你是否return,只要你不改变实际对象或它里面的任何对象.
,改变参考很好
仅仅改变变量所指的内容不会改变对象:
// good: local variable called "state" refers to a different number
state = state + 1
// good: local variable called "state" refers to a different array
state = state.concat([42])
// good: local variable called "state" refers to a different string
state = state + ", lol"
然而,在对象本身或它链接到的对象
内部改变某些东西 ,无论是否深入,都是突变,Redux 不允许:
// bad: object that local variable "state" refers to has been mutated
state.counter = state.counter + 1
// bad: object that local variable "state" refers to has been mutated
var sameObjectAsState = state
state.counter = state.counter + 1
// bad: array that local variable "state" refers to has been mutated
state.push(42)
// bad: array that local variable "state" refers to has been mutated
var sameArrayAsState = state
sameArrayAsState.push(42)
// bad: object that is linked from the object that local variable "state" refers to has been mutated
state.something.deep.counter = 42
// bad: object that is linked from the object that local variable "state" refers to has been mutated
var somethingDeep = state.something.deep
somethingDeep.counter = 42
目前我还不能使用 ES6/ES2015,而且我坚持使用 ES5 来编写 Redux reducers。由于 reducer 的状态参数必须是不可变的,即使它是未定义的,我想出了以下模式:
function myState( state, action ) {
if ( typeof state === 'undefined' ) {
return myState( { value1: 'foo', value2: 'bar' }, action );
}
// actual state calculation here
}
关于如何使用 ES5 确保默认值的任何替代建议或意见?
编辑: 经过一些问题和建议:我进行递归调用的原因是我非常重视 "state is immutable"。因此,即使 state
参数为 undefined
,我也不会更改参数变量本身。我是不是把不变性看得太过分了?
另一种选择是这样的:
var initialState = { value1: 'foo', value2: 'bar' };
function myState( state, action ) {
state = state || initialState;
// actual state calculation here
}
Redux 不会强制你使用默认的参数语法。它只关心当它给你 undefined
作为状态时,你 return 其他东西,以便你的应用程序能够使用初始状态树启动。
ES6 中的这个函数:
function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state + 1
default:
return state
}
}
相当于ES5中的这个函数:
function counter(state, action) {
if (state === undefined) {
state = 0
}
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state + 1
default:
return state
}
}
验证这一点的一个好方法是run this code through the Babel REPL。
The reason I do a recursive call is that I take the "state is immutable" very seriously. So even when the state parameter is undefined, I don't change the parameter variable itself.
这里不需要递归调用。我认为您的问题可能包含一些关于 突变和引用分配之间差异的混淆。
写的时候
var x = { lol: true }
x.lol = false
你正在变异 x
对象。这是 Redux 所不允许的。
但是当你写
var x = { lol: true }
x = { lol: false }
原始对象保持完整。 x
“绑定”(也称为“变量”)刚刚开始指向另一个对象。
Redux 不关心你是否更改了 state
参数所指的内容。它在您的函数中是本地的。不管你是否return,只要你不改变实际对象或它里面的任何对象.
仅仅改变变量所指的内容不会改变对象:
// good: local variable called "state" refers to a different number
state = state + 1
// good: local variable called "state" refers to a different array
state = state.concat([42])
// good: local variable called "state" refers to a different string
state = state + ", lol"
然而,在对象本身或它链接到的对象
内部改变某些东西 ,无论是否深入,都是突变,Redux 不允许:// bad: object that local variable "state" refers to has been mutated
state.counter = state.counter + 1
// bad: object that local variable "state" refers to has been mutated
var sameObjectAsState = state
state.counter = state.counter + 1
// bad: array that local variable "state" refers to has been mutated
state.push(42)
// bad: array that local variable "state" refers to has been mutated
var sameArrayAsState = state
sameArrayAsState.push(42)
// bad: object that is linked from the object that local variable "state" refers to has been mutated
state.something.deep.counter = 42
// bad: object that is linked from the object that local variable "state" refers to has been mutated
var somethingDeep = state.something.deep
somethingDeep.counter = 42