Store: the core Redux store methods">Store: the core Redux store methods">
跳至主要内容

商店

商店保存着您应用程序的整个 状态树。 改变其中状态的唯一方法是向它分发一个 动作,这将触发 根 reducer 函数 计算新的状态。

商店不是一个类。 它只是一个带有几个方法的对象。

要创建一个商店,将您的根 reducer 函数 传递给 Redux Toolkit 的 configureStore 方法,它将使用良好的默认配置设置一个 Redux 商店。(或者,如果您还没有使用 Redux Toolkit,您可以使用原始的 createStore 方法,但我们建议您尽快 迁移您的代码以使用 Redux Toolkit

商店方法

getState()

返回您应用程序的当前状态树。 它等于商店的 reducer 最后返回的值。

返回值

(any): 您应用程序的当前状态树。


dispatch(action)

分发一个 action。这是触发状态改变的唯一方式。

商店的 reducer 函数将使用当前的 getState() 结果和给定的 action 同步调用。它的返回值将被视为下一个状态。它将从现在开始从 getState() 返回,并且更改监听器将立即被通知。

注意

如果你试图从 reducer 内部调用 dispatch,它将抛出一个错误,提示 "Reducers may not dispatch actions." Reducers 是纯函数 - 它们只能返回一个新的状态值,并且不能有副作用(而分发是一个副作用)。

在 Redux 中,订阅在根 reducer 返回新状态后被调用,因此你可以在订阅监听器中分发。你只被禁止在 reducer 内部分发,因为它们不能有副作用。如果你想对一个 action 产生副作用,正确的地方是在潜在的异步 action creator 中。

参数

  1. action (Object): 一个描述对你的应用程序有意义的更改的普通对象。Action 是将数据放入商店的唯一方式,因此任何数据,无论是来自 UI 事件、网络回调还是其他来源(如 WebSockets),最终都需要作为 action 分发。Action 必须有一个 type 字段,用于指示正在执行的 action 类型。类型可以定义为常量,并从另一个模块导入。最好使用字符串作为 type,而不是 Symbols,因为字符串是可序列化的。除了 type 之外,action 对象的结构实际上取决于你。如果你感兴趣,可以查看 Flux Standard Action,了解如何构建 action 的建议。

返回值

(Object): 派发的动作(参见注释)。

注释

通过调用 [`createStore`](/api/createstore) 获取的“普通”存储实现仅支持普通对象动作,并立即将它们传递给 reducer。

但是,如果您使用 applyMiddleware 包装 createStore,中间件可以以不同的方式解释动作,并提供对分派 异步动作 的支持。异步动作通常是异步原语,如 Promise、Observable 或 thunk。

中间件由社区创建,默认情况下不与 Redux 一起提供。您需要显式安装诸如 redux-thunkredux-promise 之类的包才能使用它。您也可以创建自己的中间件。

要了解如何描述异步 API 调用,在动作创建者中读取当前状态,执行副作用,或将它们链接起来以按顺序执行,请参阅 applyMiddleware 的示例。

示例

import { createStore } from 'redux'
const store = createStore(todos, ['Use Redux'])

function addTodo(text) {
return {
type: 'ADD_TODO',
text
}
}

store.dispatch(addTodo('Read the docs'))
store.dispatch(addTodo('Read about the middleware'))

subscribe(listener)

添加一个更改监听器。每当分派动作时,它都会被调用,并且状态树的某些部分可能已发生更改。然后,您可以在回调中调用 getState() 来读取当前状态树。

您可以在更改监听器中调用 dispatch(),但有以下注意事项

  1. 监听器应仅在响应用户操作或在特定条件下(例如,当存储具有特定字段时分派动作)调用 dispatch()。在没有任何条件的情况下调用 dispatch() 在技术上是可能的,但会导致无限循环,因为每次 dispatch() 调用通常都会再次触发监听器。

  2. 订阅在每次 dispatch() 调用之前被快照。如果您在调用监听器时订阅或取消订阅,这不会对当前正在进行的 dispatch() 产生任何影响。但是,下一个 dispatch() 调用(无论嵌套与否)都将使用订阅列表的最新快照。

  3. 监听器不应该期望看到所有状态更改,因为状态可能在嵌套的 dispatch() 期间多次更新,然后才调用监听器。但是,可以保证在 dispatch() 开始之前注册的所有订阅者将在其退出时使用最新状态被调用。

这是一个低级 API。大多数情况下,您不会直接使用它,而是会使用 React(或其他)绑定。如果您经常使用回调作为响应状态更改的钩子,您可能需要编写一个自定义的 observeStore 实用程序Store 也是一个Observable,因此您可以使用像RxJS这样的库来订阅更改。

要取消订阅更改监听器,请调用 subscribe 返回的函数。

参数

  1. listener (函数):每次分派操作且状态树可能已更改时要调用的回调。您可以在此回调中调用 getState() 来读取当前状态树。可以合理地预期存储的 reducer 是一个纯函数,因此您可以比较状态树中某些深度路径的引用,以了解其值是否已更改。
返回值

(函数):取消订阅更改监听器的函数。

示例
function select(state) {
return state.some.deep.property
}

let currentValue
function handleChange() {
let previousValue = currentValue
currentValue = select(store.getState())

if (previousValue !== currentValue) {
console.log(
'Some deep nested property changed from',
previousValue,
'to',
currentValue
)
}
}

const unsubscribe = store.subscribe(handleChange)
unsubscribe()

replaceReducer(nextReducer)

替换存储当前用于计算状态的 reducer。

这是一个高级 API。如果您应用实施代码拆分,并且想要动态加载一些 reducer,您可能需要此 API。如果您为 Redux 实施热重载机制,您也可能需要此 API。

参数

  1. nextReducer (函数) 存储要使用的下一个 reducer。