为什么Redux要限制reducer内部的state访问范围?设计考量是什么?
Redux 限制 reducer 访问全局 state 的核心设计考量
- 保障 reducer 的纯函数特性
Redux 从设计上要求所有 reducer 必须是纯函数,纯函数的核心规则就是相同输入永远返回相同输出,不依赖外部可变状态、也不产生任何副作用。如果允许 reducer 直接访问全局 state,就意味着 reducer 的输出除了依赖自身管辖的分片 state、传入的 action 之外,还会依赖全局其他位置的状态,完全破坏纯函数的约定,同一个 action 触发多次可能因为全局其他状态的变化得到完全不同的结果。 - 保证状态更新的可预测性与可调试性
可预测性是 Redux 最核心的设计目标之一,配套的时间旅行调试、action 回放、redo/undo 等能力,全部建立在「给定 action 和初始 state,reducer 输出永远固定」的基础上。如果 reducer 可以访问全局 state,上述调试能力会直接失效,你在 DevTools 看到某个 action 触发时,无法仅通过 action 和对应分片的 state 推断状态变化原因,还需要排查全局所有其他状态的影响,调试成本会指数级上升。 - 强制状态逻辑的分层解耦
Redux 推荐按业务模块拆分 reducer,每个 reducer 只负责维护自己管辖的那部分状态,天然实现了模块间的逻辑隔离。如果允许 reducer 跨分片访问全局 state,很容易导致不同模块的状态逻辑强耦合,比如商品模块的 reducer 直接读取用户模块的会员等级计算折扣,后续你想要抽离商品模块单独复用的时候,必须连带把用户模块的状态逻辑也一起迁移,维护成本会大幅提升。
对应需求的标准实现方案
你提到的在 thunk 中访问全局 state 是官方推荐的标准实现,除此之外也可以根据场景选择以下方案:
- 在 action creator 中通过
getState()拿到完整全局 state,把需要用到的其他分片数据提前组装到 action 的 payload 中再 dispatch,reducer 直接从 payload 取参数即可,不需要额外访问外部状态 - 如果是频繁用到的跨分片数据计算,可以封装成全局 selector,在组件或者 thunk 中调用 selector 拿到计算结果后再传递给 reducer
内容的提问来源于stack exchange,提问作者unclebob
相关产品推荐
相关产品推荐

