术语表
这是一个 Redux 核心术语的术语表,以及它们的类型签名。这些类型使用 Flow 符号 进行记录。
状态
type State = any
状态(也称为状态树)是一个广泛的术语,但在 Redux API 中,它通常指的是由 store 管理并由 getState()
返回的单个状态值。它表示 Redux 应用程序的整个状态,通常是一个深度嵌套的对象。
按照惯例,顶层状态是一个对象或其他键值集合,例如 Map,但从技术上讲它可以是任何类型。不过,您应该尽力保持状态可序列化。不要在其中放入任何无法轻松转换为 JSON 的内容。
操作
type Action = Object
一个操作是一个表示改变状态意图的普通对象。操作是将数据传入存储的唯一方式。任何数据,无论是来自 UI 事件、网络回调还是其他来源(如 WebSockets),最终都需要作为操作进行分发。
操作必须具有一个type
字段,用于指示正在执行的操作类型。类型可以定义为常量并从另一个模块导入。对于type
,最好使用字符串而不是符号,因为字符串是可序列化的。
除了type
之外,操作对象的结构实际上取决于你。如果你有兴趣,可以查看Flux 标准操作,了解有关如何构建操作的建议。
另请参阅下面的异步操作。
Reducer
type Reducer<S, A> = (state: S, action: A) => S
一个Reducer是一个接受累积值和一个值并返回一个新的累积值的函数。它们用于将一组值缩减为单个值。
Reducer 并非 Redux 独有——它们是函数式编程中的一个基本概念。即使大多数非函数式语言(如 JavaScript)也具有用于缩减的内置 API。在 JavaScript 中,它是Array.prototype.reduce()
。
在 Redux 中,累积值是状态对象,累积的值是操作。Reducer 根据先前状态和操作计算新的状态。它们必须是纯函数——对于给定输入返回完全相同输出的函数。它们还应该没有副作用。这就是使热重载和时间旅行等令人兴奋的功能成为可能的因素。
Reducer 是 Redux 中最重要的概念。
不要将 API 调用放入 Reducer 中。
分发函数
type BaseDispatch = (a: Action) => Action
type Dispatch = (a: Action | AsyncAction) => any
一个分发函数(或简称为分发函数)是一个接受操作或异步操作的函数;然后它可能会或可能不会将一个或多个操作分发到存储中。
我们必须区分一般意义上的分发函数和存储实例提供的基本dispatch
函数(不带任何中间件)。
基本分发函数始终同步地将操作发送到存储的 Reducer,以及存储返回的先前状态,以计算新的状态。它期望操作是准备由 Reducer 使用的普通对象。
中间件 包装了基础的 dispatch 函数。它允许 dispatch 函数除了处理 action 之外,还可以处理 异步 action。中间件可以在将 action 或异步 action 传递到下一个中间件之前,对它们进行转换、延迟、忽略或以其他方式解释。有关更多信息,请参见下文。
Action Creator
type ActionCreator<A, P extends any[] = any[]> = (...args: P) => Action | AsyncAction
Action Creator 顾名思义,就是一个创建 action 的函数。不要混淆这两个术语——再次强调,action 是信息的载体,而 action creator 是一个创建 action 的工厂。
调用 action creator 只能生成一个 action,但不会 dispatch 它。您需要调用 store 的 dispatch
函数才能真正地触发状态变更。有时我们会说 绑定 action creator,指的是调用 action creator 并立即将其结果 dispatch 到特定 store 实例的函数。
如果 action creator 需要读取当前状态、执行 API 调用或导致副作用(例如路由转换),它应该返回一个 异步 action,而不是一个 action。
异步 Action
type AsyncAction = any
异步 action 是一个发送到 dispatch 函数的值,但尚未准备好供 reducer 使用。它将被 中间件 转换为 action(或一系列 action),然后发送到基础的 dispatch()
函数。异步 action 可能具有不同的类型,具体取决于您使用的中间件。它们通常是异步原语,例如 Promise 或 thunk,它们不会立即传递给 reducer,而是在操作完成后触发 action dispatch。
中间件
type MiddlewareAPI = { dispatch: Dispatch, getState: () => State }
type Middleware = (api: MiddlewareAPI) => (next: Dispatch) => Dispatch
中间件是一个高阶函数,它组合一个 dispatch 函数 以返回一个新的 dispatch 函数。它通常将 异步 action 转换为 action。
中间件可以使用函数组合进行组合。它对于记录 action、执行副作用(例如路由)或将异步 API 调用转换为一系列同步 action 非常有用。
有关中间件的详细介绍,请参见 applyMiddleware(...middlewares)
。
Store
type Store = {
dispatch: Dispatch
getState: () => State
subscribe: (listener: () => void) => () => void
replaceReducer: (reducer: Reducer) => void
}
Store 是一个对象,它保存应用程序的状态树。在 Redux 应用程序中,应该只有一个 store,因为组合发生在 reducer 层级。
dispatch(action)
是上面描述的基础 dispatch 函数。getState()
返回存储的当前状态。subscribe(listener)
注册一个在状态更改时调用的函数。replaceReducer(nextReducer)
可用于实现热重载和代码拆分。你很可能不会使用它。
查看完整的 存储 API 参考 以了解更多详细信息。
存储创建者
type StoreCreator = (reducer: Reducer, preloadedState: ?State) => Store
存储创建者是一个创建 Redux 存储的函数。与分派函数一样,我们必须区分 Redux 包中导出的基本存储创建者 createStore(reducer, preloadedState)
与从存储增强器返回的存储创建者。
存储增强器
type StoreEnhancer = (next: StoreCreator) => StoreCreator
存储增强器是一个高阶函数,它组合一个存储创建者以返回一个新的增强存储创建者。这类似于中间件,因为它允许你以可组合的方式更改存储接口。
存储增强器与 React 中的高阶组件概念非常相似,高阶组件有时也称为“组件增强器”。
因为存储不是一个实例,而是一个简单的函数集合,所以可以轻松地创建和修改副本,而不会改变原始存储。在 compose
文档中有一个演示这一点的示例。
你很可能永远不会编写存储增强器,但你可能会使用 开发者工具 提供的增强器。它使时间旅行成为可能,而应用程序并不知道它正在发生。有趣的是,Redux 中间件实现 本身就是一个存储增强器。