如何在ES5 Redux reducer中初始化默认数据?

chi*_*org 6 javascript ecmascript-5 redux

暂时我不能使用ES6/ES2015而且我坚持使用ES5来编写Redux减速器.由于reducer的state参数必须是不可变的,即使它未定义,我想出了以下模式:

function myState( state, action ) {
    if ( typeof state === 'undefined' ) {
        return myState( { value1: 'foo', value2: 'bar' }, action );
    }
    // actual state calculation here
}
Run Code Online (Sandbox Code Playgroud)

有关如何使用ES5确保默认值的任何其他建议或意见?

编辑:经过一些问题和建议:我做递归调用的原因是我非常认真地对待"状态是不可变的".所以即使state参数是undefined,我也不会改变参数变量本身.我把不变性带到了太远了吗?

Dan*_*mov 28

Redux不会强制您使用默认参数语法.它只关心当它将您undefined作为状态时,您返回其他内容,以便您的应用程序能够使用初始状态树启动.

ES6中的这个功能:

function counter(state = 0, action) {
  switch (action.type) {
  case 'INCREMENT':
    return state + 1
  case 'DECREMENT':
    return state + 1
  default:
    return state
  }
}
Run Code Online (Sandbox Code Playgroud)

相当于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 Code Online (Sandbox Code Playgroud)

验证这一点的一个好方法是通过Babel REPL运行此代码.


我做递归调用的原因是我非常认真地对待"状态是不可变的".因此,即使未定义state参数,我也不会更改参数变量本身.

这里不需要递归调用.我认为你的问题可能包含一些关于突变和参考分配之间差异的混淆.

当你写作

var x = { lol: true }
x.lol = false
Run Code Online (Sandbox Code Playgroud)

突变x对象.这是Redux不允许的.

但是当你写作

var x = { lol: true }
x = { lol: false }
Run Code Online (Sandbox Code Playgroud)

原始对象保持不变.x"绑定"(也称为"变量")只是开始指向不同的对象.

Redux并不关心你是否改变了state参数所指的内容.它是您的功能的本地.无论您是否返回,只要您不改变实际对象或其中的任何对象,就更改引用.

只是更改变量引用的内容不会改变对象:

// 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"
Run Code Online (Sandbox Code Playgroud)

然而,改变对象本身内部或者链接到的对象(无论是否深层次)都是一种变异,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
Run Code Online (Sandbox Code Playgroud)