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

标签 javascript redux ecmascript-5

目前我还不能使用 ES6/ES2015,我只能使用 ES5 来编写 Redux reducer。由于 reducer 的状态参数必须是不可变的,即使它是未定义的,我想出了以下模式:

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

关于如何使用 ES5 确保默认值的任何替代建议或意见?

编辑: 经过一些问题和建议:我进行递归调用的原因是我非常重视“状态不可变”。因此,即使 state 参数为 undefined,我也不会更改参数变量本身。我对不变性的理解是否太过分了?

最佳答案

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

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“绑定(bind)”(也称为“变量”)只是开始指向不同的对象。

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"

然而,改变对象内部的某些东西,或者它链接到的对象,无论是否深入,都是一种突变,并且是 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

关于javascript - 如何在 ES5 Redux reducer 中初始化默认数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35629350/

相关文章:

javascript - 导航时加载 GIF 图像

javascript - Angular/Redux 保持状态的正确方法

reactjs - 是否可以在 Redux/React 中分离组件的表示和逻辑?

javascript - 兼容 ES6 功能

javascript - 自调用函数中的不可变 undefined

javascript - 避免在外部调用原型(prototype)方法时丢失对象实例

javascript - 想知道如何调试 Node.js learnyounode "filter ls"练习

javascript - 连接到组件时修改 redux 中的数据

javascript - 如何导入与包含它们的文件夹同名的文件?

javascript - 使用 Controller 通过作用域树进行 Angular 数据传播