javascript - Redux reducer 作为纯函数

标签 javascript reactjs redux

我总是初始化 redux reducer 中的日期,这样做:

const initialState = {
  dateFilter: new Date()
}

const reducer = (state = initialState, action) => {
// reducer code
}

export default reducer;

我不确定我是否以正确的方式这样做,因为据我了解, reducer 必须是纯函数,而 new Date 不是纯函数。也许这更像是一个js问题,因为我不明白这里的reducer函数是否是纯粹的。

最佳答案

只要您不在 //reducer 代码 中执行其他操作,它就是纯粹的:)。例如再次调用new Date(如第二个示例)

const initialState = {
  dateFilter: new Date()
}

const reducer = (state = initialState, action) => {
  switch(action.type) {
    
    default: return state
  }
}

console.log(`Reducer is ${
  reducer(undefined, {type: '@@INIT'}) === reducer(undefined, {type: '@@INIT'})
  ? 'pure'
  : 'not pure'}`)

这个不是

const initialState = () => ({
  dateFilter: new Date()
})

const reducer = (state = initialState(), action) => {
  switch(action.type) {
    
    default: return state
  }
}

console.log(`Reducer is ${
  reducer(undefined, {type: '@@INIT'}) === reducer(undefined, {type: '@@INIT'})
  ? 'pure'
  : 'not pure'}`)

UPD 正如 @spender 提到的,initialState 必须是不可变的。这在 javascript 中很难保证,因为默认情况下对象和日期都是可变的。为了保证不变性,可以使用

const initialState = Object.freeze({ // freeze the object
  dateFilter: Date.now() // use immutable number instead of Date instance
})

还有 wiki 的 TLDR

纯函数是一种输出依赖于输入的函数,并且不执行任何可观察到的副作用。想想加法 const add = (a, b) => a + b add(1, 2) 总是 3 并且没有导弹被推出。如果函数是纯函数,您可以安全:缓存结果、重新排序或延迟调用、对相同参数多次调用函数等等。

  • add(1, 2) 可以替换为 3。如果一个函数说计算它被调用的次数,那是不可能的。
  • add(add(1,2), add(2,3)) 您可以先执行 add(1, 2) 然后 add(2 , 3) 或反之亦然。如果一个函数说记录到控制台,这是不可能的。
  • 等等。

对纯函数的冒烟测试是“相同的输入产生相同的输出”。

不幸的是(或者幸运的是:))默认情况下,js 中的函数不需要是纯函数,并且通常很难保证它们是纯函数,因为 javascript 内置对象默认情况下是可变的。

即使是上面的 add 函数也可能会产生副作用,因此您必须对纯度定义持保留态度。

const add = (a, b) => a + b

const a = {
  _i: 1,
  valueOf() {
    console.log('Missiles launched')
    return this._i++;
  }
}

console.log(add(a, 1), add(a, 1))

关于javascript - Redux reducer 作为纯函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57007601/

相关文章:

Redux 工具包-selectById

javascript - 使用 jQuery 根据输入的值创建多个输入字段

reactjs - 如何使用redux动态添加元素

javascript - React Context 和 hookrouter 不会在组件挂载时重定向

javascript - 重新呈现我的 react 组件的最佳模式?

reactjs - React Redux 错误类型错误 : sourceSelector is not a function

javascript 如何从 onclick 中删除父 div

javascript - 将 IP 地理定位与 Rails 3 结合使用

javascript - 从大数组中删除重复的字符串

typescript - 类型 'never' 上不存在属性 ID