Skip to main content

Reducer 必备概念

就像 前面教程的 Reducers 中描述的一样,一个 Redux reducer 函数需要具备:

  • 格式为 (previousState, action) => newState 这样的签名,与 Array.prototype.reduce(reducer, ?initialValue) 这个函数很相似。
  • 应该是"纯"函数,纯函数意味着
    • 无副作用(禁止调用 API,修改非本地对象或变量)
    • 不能调用非纯函数。比如 Date.now()Math.random()
    • 不能修改它的 state。这意味着 state 的更新应该在 "不可变(immutable)"的理念下完成,这就是说总是去返回一个新的更新后的对象,而不是直接去修改原始的 state tree。
关于不可变(immutability)和突变(mutation)以及副作用#

突变是一种不鼓励的做法,因为它通常会打乱调试的过程,以及 React Redux 的 connect 函数:

  • 对于调试过程, Redux DevTools 期望重放 action 记录时能够输出 state 值,而不会改变任何其他的状态。突变或者异步行为会产生一些副作用,可能使调试过程中的行为被替换,导致破坏了应用。
  • 对于 React Redux connect 来说,为了确定一个组件(component)是否需要更新,它会检查从 mapStateToProps 中返回的值是否发生改变。为了提升性能,connect 使用了一些依赖于不可变 state 的方法。并且使用浅引用(shallow reference)来检测状态的改变。这意味着直接修改对象或者数组是不会被检测到的并且组件不会被重新渲染。

其他的副作用像在 reducer 中生成唯一的 ID 或者时间戳时也会导致代码的不可预测并且难以调试和测试。

因为上面这些规则,在去学习具体的组织 Redux reducer 的技术之前,了解并完全理解下面这些核心概念是十分重要的。

Redux Reducer 基础#

核心概念

  • 理解 state 和 state shape
  • 通过拆分 state 来确定各自的更新职责(reducer 组合
  • 高阶 reducers
  • 定义 reducer 的初始化状态

阅读列表

纯函数和副作用#

核心概念

  • 副作用
  • 纯函数
  • 如何理解组合函数

Reading List:

阅读列表

不可变数据的管理#

核心概念

  • 可变与不可变
  • 安全地以不可变的方式更新对象和数组
  • 避免在函数和语句中突变 state

阅读列表

范式化数据#

核心概念

  • 数据库的组织结构
  • 拆分相关/嵌套数据到单独的表中
  • 为每个被赋值的对象都存储一个单独的标识
  • 通过 ID 引用对象
  • 通过对象 ID 来查找表,通过一组 ID 来记录顺序
  • 通过关系来联系各个对象

阅读列表