跳到主要内容

 

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 和使用模式,接受 reducer,preloadedState,middleware,enhancers 和 devtools 的命名字段,以及更好的 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 增强器被组合在一起