跳到主要内容

 

configureStore

创建 Redux 存储的标准方法。它内部使用低级 Redux 核心 createStore 方法,但包装了该方法,为存储设置提供良好的默认值,以提供更好的开发体验。

目的和行为

标准的 Redux 存储设置通常需要多个配置部分:

  • 将切片 reducer 合并到根 reducer
  • 创建中间件增强器,通常使用 thunk 中间件或其他副作用中间件,以及可能用于开发检查的中间件
  • 添加 Redux DevTools 增强器,并将增强器组合在一起
  • 调用 createStore

传统的 Redux 使用模式通常需要复制粘贴几十行样板代码来实现这一点。

Redux Toolkit 的 configureStore 简化了该设置过程,为您完成所有这些工作。一次调用 configureStore 将:

  • 调用 combineReducers 将您的切片 reducer 合并到根 reducer 函数
  • 添加 thunk 中间件并调用 applyMiddleware
  • 在开发中,自动添加更多中间件以检查常见错误,如意外地改变状态
  • 自动设置 Redux DevTools Extension 连接
  • 调用 createStore 使用该根 reducer 和这些配置选项创建 Redux 存储

与原始的 createStore 相比,configureStore 还提供了改进的 API 和使用模式,接受 reducerpreloadedStatemiddlewareenhancersdevtools 的命名字段,以及更好的 TS 类型推断。

参数

configureStore 接受一个单一的配置对象参数,具有以下选项:


interface ConfigureStoreOptions<
S = any,
A extends Action = UnknownAction,
M extends Tuple<Middlewares<S>> = Tuple<Middlewares<S>>
E extends Tuple<Enhancers> = Tuple<Enhancers>,
P = S
> {
/**
* 将用作根 reducer 的单个 reducer 函数,或者
* 将传递给 `combineReducers()` 的切片 reducer 对象。
*/
reducer: Reducer<S, A, P> | ReducersMapObject<S, A, P>

/**
* 要安装的 Redux 中间件数组。如果未提供,则默认为
* `getDefaultMiddleware()` 返回的中间件集。
*/
middleware?: ((getDefaultMiddleware: CurriedGetDefaultMiddleware<S>) => M) | M

/**
* 是否启用 Redux DevTools 集成。默认为 `true`。
*
* 可以通过传递 Redux DevTools 选项进行额外配置
*/
devTools?: boolean | DevToolsOptions

/**
* 初始状态,与 Redux 的 createStore 相同。
* 您可以选择指定它以从服务器中的通用应用程序中提取状态,
* 或恢复以前序列化的用户会话。如果您使用 `combineReducers()` 生成根 reducer
* 函数(直接或间接通过将对象作为 `reducer` 传递),
* 这必须是一个与 reducer 映射键形状相同的对象。
*/
preloadedState?: P

/**
* 要应用的存储增强器。参见 Redux 的 `createStore()`。
* 所有增强器都将在 DevTools Extension 增强器之前包含。
* 如果您需要自定义增强器的顺序,提供一个回调
* 函数,该函数将接收 getDefaultEnhancers,
* 并应返回一个新数组(例如 `getDefaultEnhancers().concat(offline)`)。
* 如果您只需要添加中间件,可以使用 `middleware` 参数代替。
*/
enhancers?: (getDefaultEnhancers: GetDefaultEnhancers<M>) => E | E
}

function configureStore<
S = any,
A extends Action = UnknownAction,
M extends Tuple<Middlewares<S>> = Tuple<Middlewares<S>>
E extends Tuple<Enhancers> = Tuple<Enhancers>,
P = S
>(options: ConfigureStoreOptions<S, A, M, E, P>): EnhancedStore<S, A, M, E>

reducer

如果这是一个单一的函数,它将直接用作存储的根 reducer。

如果它是一个切片 reducer 的对象,如 {users : usersReducer, posts : postsReducer}configureStore 将自动通过将此对象传递给 Redux combineReducers 实用程序 创建根 reducer。

middleware

一个将接收 getDefaultMiddleware 作为其参数的回调, 并应返回一个中间件数组。

如果提供了此选项,它应返回您 希望添加到存储的所有中间件函数。configureStore 将自动将这些传递给 applyMiddleware

如果未提供,configureStore 将调用 getDefaultMiddleware 并使用 它返回的中间件函数数组。

有关 middleware 参数的工作方式以及默认添加的中间件列表的更多详细信息,请参见 getDefaultMiddleware 文档页面

Tuple

Typescript 用户需要使用 Tuple 实例(如果不使用 getDefaultMiddleware 结果,它已经是一个 Tuple),以获得更好的推断。

import { configureStore, Tuple } from '@reduxjs/toolkit'

configureStore({
reducer: rootReducer,
middleware: () => new Tuple(additionalMiddleware, logger),
})

仅 Javascript 用户可以自由选择使用普通数组。

devTools

如果这是一个布尔值,它将用于指示 configureStore 是否应自动启用对 Redux DevTools 浏览器扩展 的支持。

如果它是一个对象,那么将启用 DevTools 扩展,并将选项对象传递给 composeWithDevtools()。请参阅 DevTools 扩展文档中的 EnhancerOptions 以获取 可用的特定选项列表。

默认为 true

trace

Redux DevTools 扩展最近添加了 支持显示操作堆栈跟踪 的功能,这可以显示每个操作被分派的确切位置。 捕获这些跟踪可能会增加一些开销,因此 DevTools 扩展允许用户通过 设置 'trace' 参数 来配置是否捕获操作堆栈跟踪。 如果通过传递 true 或一个对象启用了 DevTools,那么 configureStore 将默认在开发模式下启用捕获操作堆栈跟踪。

preloadedState

一个可选的初始状态值,它会被传递给 Redux 的 createStore 函数。

enhancers

一个回调函数,用于自定义增强器数组。

此回调返回的增强器将被传递给 Redux 的 compose 函数,并且组合的增强器将被传递给 createStore

Dev Tools

这不应该包括 Redux DevTools 扩展的 composeWithDevTools,因为这已经由 configureStore 处理了。

例如:enhancers: () => new Tuple(offline) 将导致最终的设置为 [offline, devToolsExtension]

如果未提供,configureStore 将调用 getDefaultEnhancers 并使用它返回的增强器数组(包括指定的中间件的 applyMiddleware)。

如果你希望添加或自定义默认的增强器,你可以传递一个回调函数,该函数将接收 getDefaultEnhancers 作为其参数,并应返回一个增强器数组。

例如:enhancers: (defaultEnhancers) => defaultEnhancers.prepend(offline) 将导致最终的设置为 [offline, applyMiddleware, devToolsExtension]

有关 enhancer 参数的工作方式以及默认添加的增强器列表的更多详细信息,请参见 getDefaultEnhancers 文档页面

Middleware

如果你不使用 getDefaultEnhancers 而是返回一个数组,applyMiddleware 增强器将 不会 被使用。

如果提供了任何中间件(或保留为默认值)但未包含在最终的增强器列表中,configureStore 将在控制台中发出警告。

// 警告 - 中间件被定制但未包含在最终的增强器中
configureStore({
reducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger)
enhancers: [offline(offlineConfig)],
})

// 正常 - 包含了默认的增强器
configureStore({
reducer,
enhancers: (getDefaultEnhancers) => getDefaultEnhancers().concat(offline(offlineConfig)),
})

// 也允许
configureStore({
reducer,
middleware: () => [],
enhancers: () => [offline(offlineConfig)],
})

注意,如果使用 Typescript,middleware 选项需要在增强器选项之前提供,因为 getDefaultEnhancers 的类型取决于其结果。

Tuple

Typescript 用户需要使用 Tuple 实例(如果不使用 getDefaultEnhancer 的结果,该结果已经是一个 Tuple),以便更好的推断。

import { configureStore, Tuple } from '@reduxjs/toolkit'

configureStore({
reducer: rootReducer,
enhancers: () => new Tuple(offline),
})

仅使用 Javascript 的用户可以自由选择使用普通数组。

使用

基本示例

// 文件: reducers.ts noEmit
import type { Reducer } from '@reduxjs/toolkit'
declare const rootReducer: Reducer<{}>
export default rootReducer

// 文件: store.ts
import { configureStore } from '@reduxjs/toolkit'

import rootReducer from './reducers'

const store = configureStore({ reducer: rootReducer })
// 现在的 store 已经添加了 redux-thunk,并且已经打开了 Redux DevTools 扩展

完整示例

// 文件: todos/todosReducer.ts noEmit
import type { Reducer } from '@reduxjs/toolkit'
declare const reducer: Reducer<{}>
export default reducer

// 文件: visibility/visibilityReducer.ts noEmit
import type { Reducer } from '@reduxjs/toolkit'
declare const reducer: Reducer<{}>
export default reducer

// 文件: store.ts
import { configureStore } from '@reduxjs/toolkit'

// 我们将使用 redux-logger 作为添加另一个中间件的示例
import logger from 'redux-logger'

// 并使用 redux-batched-subscribe 作为添加增强器的示例
import { batchedSubscribe } from 'redux-batched-subscribe'

import todosReducer from './todos/todosReducer'
import visibilityReducer from './visibility/visibilityReducer'

const reducer = {
todos: todosReducer,
visibility: visibilityReducer,
}

const preloadedState = {
todos: [
{
text: 'Eat food',
completed: true,
},
{
text: 'Exercise',
completed: false,
},
],
visibilityFilter: 'SHOW_COMPLETED',
}

const debounceNotify = _.debounce((notify) => notify())

const store = configureStore({
reducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger),
devTools: process.env.NODE_ENV !== 'production',
preloadedState,
enhancers: (getDefaultEnhancers) =>
getDefaultEnhancers({
autoBatch: false,
}).concat(batchedSubscribe(debounceNotify)),
})

// 使用这些选项创建了 store:
// - 切片 reducer 自动传递给 combineReducers()
// - redux-thunk 和 redux-logger 被添加为中间件
// - Redux DevTools 扩展在生产环境下被禁用
// - 中间件,批量订阅和 devtools 增强器被组合在一起