Skip to main content

Redux 常见问题解答:Reducer

¥Redux FAQ: Reducers

目录

¥Table of Contents

Reducer

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

¥How do I share state between two reducers? Do I have to use combineReducers?

Redux 存储的建议结构是按键将状态对象拆分为多个“切片”或“域”,并提供单独的缩减器函数来管理每个单独的数据切片。这类似于标准 Flux 模式具有多个独立存储的方式,Redux 提供了 combineReducers 实用函数来使这种模式更容易。然而,值得注意的是,combineReducers 不是必需的 - 它只是一个实用函数,适用于每个状态切片有一个单一化简器函数的常见用例,并带有用于数据的纯 JavaScript 对象。

¥The suggested structure for a Redux store is to split the state object into multiple “slices” or “domains” by key, and provide a separate reducer function to manage each individual data slice. This is similar to how the standard Flux pattern has multiple independent stores, and Redux provides the combineReducers utility function to make this pattern easier. However, it's important to note that combineReducers is not required—it is simply a utility function for the common use case of having a single reducer function per state slice, with plain JavaScript objects for the data.

许多用户后来想尝试在两个 reducer 之间共享数据,但发现 combineReducers 不允许他们这样做。可以使用以下几种方法:

¥Many users later want to try to share data between two reducers, but find that combineReducers does not allow them to do so. There are several approaches that can be used:

  • 如果一个 reducer 需要知道来自另一个状态切片的数据,则可能需要重新组织状态树形状,以便单个 reducer 能够处理更多的数据。

    ¥If a reducer needs to know data from another slice of state, the state tree shape may need to be reorganized so that a single reducer is handling more of the data.

  • 你可能需要编写一些自定义函数来处理其中一些操作。这可能需要用你自己的顶层 reducer 函数替换 combineReducers。你还可以使用 reduce-reducers 等实用程序来运行 combineReducers 来处理大多数操作,还可以为跨状态切片的特定操作运行更专门的 reducer。

    ¥You may need to write some custom functions for handling some of these actions. This may require replacing combineReducers with your own top-level reducer function. You can also use a utility such as reduce-reducers to run combineReducers to handle most actions, but also run a more specialized reducer for specific actions that cross state slices.

  • 具有异步逻辑的中间件redux-thunk 可以通过 getState() 访问整个状态。动作创建者可以从状态中检索附加数据并将其放入动作中,以便每个 reducer 都有足够的信息来更新自己的状态切片。

    ¥Middleware with async logic such as redux-thunk have access to the entire state through getState(). An action creator can retrieve additional data from the state and put it in an action, so that each reducer has enough information to update its own state slice.

一般来说,请记住,reducer 只是函数 - 你可以以任何你想要的方式组织它们并细分它们,并且鼓励你将它们分解为更小的、可重用的函数(“reducer 组合”)。当你这样做时,如果子 reducer 需要额外的数据来计算其下一个状态,你可以从父 reducer 传递自定义的第三个参数。你只需要确保它们一起遵循 reducer 的基本规则:(state, action) => newState,并且不可变地更新状态而不是直接改变它。

¥In general, remember that reducers are just functions—you can organize them and subdivide them any way you want, and you are encouraged to break them down into smaller, reusable functions (“reducer composition”). While you do so, you may pass a custom third argument from a parent reducer if a child reducer needs additional data to calculate its next state. You just need to make sure that together they follow the basic rules of reducers: (state, action) => newState, and update state immutably rather than mutating it directly.

更多信息

¥Further information

文档

¥Documentation

讨论

¥Discussions

我是否必须使用 switch 语句来处理操作?

¥Do I have to use the switch statement to handle actions?

不。欢迎你使用任何你想要的方法来响应 reducer 中的操作。switch 语句是最常见的方法,但也可以使用 if 语句、函数查找表或创建一个将其抽象出来的函数。事实上,虽然 Redux 确实要求操作对象包含 type 字段,但你的 reducer 逻辑甚至不必依赖它来处理操作。也就是说,标准方法肯定是使用 switch 语句或基于 type 的查找表。

¥No. You are welcome to use any approach you'd like to respond to an action in a reducer. The switch statement is the most common approach, but it's fine to use if statements, a lookup table of functions, or to create a function that abstracts this away. In fact, while Redux does require that action objects contain a type field, your reducer logic doesn't even have to rely on that to handle the action. That said, the standard approach is definitely using a switch statement or a lookup table based on type.

更多信息

¥Further information

文档

¥Documentation

讨论

¥Discussions