Skip to main content

Reducer(状态更新函数)

Redux 常见问题:Reducer(状态更新函数)

如何在两个 reducer 之间共享状态?我必须使用 combineReducers 吗?

Redux 存储推荐的结构是通过键将状态对象拆分成多个“切片”或“领域”,并为每个单独的数据切片提供一个 reducer 函数来管理。这类似于标准 Flux 模式中有多个独立的 store,Redux 提供了 combineReducers 工具函数来简化这种模式的使用。然而,需要注意的是,combineReducers必需 —— 它只是一个用于常见用例的辅助函数,即每个状态切片对应一个 reducer 函数,数据使用普通的 JavaScript 对象。

许多用户后来希望尝试在两个 reducer 之间共享数据,但发现 combineReducers 并不支持这样做。有几种解决方法:

  • 如果一个 reducer 需要了解其他状态切片的数据,可能需要重新组织状态树结构,让单个 reducer 处理更多的数据。
  • 你可能需要编写一些自定义函数来处理部分动作,这可能需要用你自己的顶层 reducer 函数替代 combineReducers。你也可以使用像 reduce-reducers 这样的工具,先用 combineReducers 处理大部分动作,同时针对跨状态切片的特定动作运行更专门的 reducer。
  • 带异步逻辑的中间件,例如 redux-thunk,可以通过 getState() 访问整个状态。一个 action 创建者可以从状态中检索额外数据并放进 action 中,使各个 reducer 拥有足够信息来更新自己的状态切片。

总的来说,记住 reducer 只是函数 —— 你可以按任何方式组织和细分它们,推荐将它们拆分为更小的、可复用的函数(“reducer 组合”)。在拆分的过程中,如果子 reducer 需要额外数据计算下一状态,你可以从父 reducer 传入自定义的第三个参数。只需确保它们共同遵守 reducer 的基本规则:(state, action) => newState,并且以不可变方式更新状态,而不是直接修改。

进一步信息

文档

讨论

我必须使用 switch 语句来处理动作吗?

不必。你可以用任何你喜欢的方法在 reducer 中响应动作。switch 语句是最常见的做法,但使用 if 语句、函数查找表,或者创建一个抽象函数来封装这部分逻辑都是可以的。事实上,虽然 Redux 要求 action 对象包含一个 type 字段,但你的 reducer 逻辑甚至不必依赖它来处理动作。话虽如此,标准做法确实是基于 type 使用 switch 语句或查找表。

进一步信息

文档

讨论