reducer 是纯函数,接收当前状态和动作并返回新状态,核心在于可预测的不可变数据转换。它通过显式输入输出、无副作用、确定性映射,实现状态更新的可测试性、可复用性和可推导性。

reducer 本质上是一个纯函数,它接收“当前状态”和“动作”,返回“新状态”。它的核心价值不在“减少”,而在于可预测的数据转换——这正是函数式编程处理数据流的典型方式。
reducer 是数据转换的标准化契约
它不是特殊语法,而是一种约定:输入两个参数(acc, item)或(state, action),返回一个新值,不修改原值。比如数组的 reduce 方法:
-
[1, 2, 3].reduce((sum, n) => sum + n, 0)把数字列表转为单个和值 -
todos.reduce((active, todo) => todo.completed ? active : active + 1, 0)把待办列表转为未完成数量
每一次调用,都是对数据结构的一次确定性映射。这种“输入→输出”的封闭性,让逻辑更易测试、复用和推导。
状态更新 = 不可变转换 + 显式依赖
在 Redux 或 Zustand 等状态管理中,reducer 被用来响应 action 更新 state。关键在于:
- 总是返回新对象/数组,例如用展开运算符
{...state, count: state.count + 1} - 不调用副作用(如 API、setTimeout),不读取外部变量(如全局时间、随机数)
- 相同 state + 相同 action → 永远得到相同 newState(纯函数特性)
这种约束看似严格,实则把“状态怎么变”从隐式逻辑(比如随意 this.setState)变成显式声明,大幅降低意外行为发生的可能。
从 map/filter 到 reduce:理解抽象层级的跃迁
map 和 filter 是特定目的的转换(一对一映射、条件筛选),而 reduce 是通用构造器:
-
arr.map(x => x * 2)可以写成arr.reduce((acc, x) => [...acc, x * 2], []) -
arr.filter(x => x > 0)等价于arr.reduce((acc, x) => x > 0 ? [...acc, x] : acc, [])
reducer 抽象出“累积+逐项处理”的模式,让你能定义任意聚合逻辑:分组、扁平化、树形展开、甚至模拟 Promise 链。它不是替代 map/filter,而是提供更底层的表达能力。
实际写 reducer 时的三个提醒
避免常见陷阱,才能真正发挥函数式优势:
- 用工具库辅助不可变操作,比如 Immer(允许“写起来像修改,实际是生成新对象”)
- 拆分复杂逻辑:主 reducer 负责路由 action,交给子 reducer 处理具体字段(组合式思维)
- 给初始 state 设计明确结构,比如
{ loading: false, data: null, error: null },让转换路径清晰可见
函数式编程不追求炫技,而是用受限的表达换来长期可维护性。reducer 就是其中最落地的一个支点——把变化变成可追踪、可重放、可推理的数据转换过程。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











