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
文档页面。
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
。
这不应该包括 Redux DevTools 扩展的 composeWithDevTools
,因为这已经由 configureStore
处理了。
例如:enhancers: () => new Tuple(offline)
将导致最终的设置为 [offline, devToolsExtension]
。
如果未提供,configureStore
将调用 getDefaultEnhancers
并使用它返回的增强器数组(包括指定的中间件的 applyMiddleware
)。
如果你希望添加或自定义默认的增强器,你可以传递一个回调函数,该函数将接收 getDefaultEnhancers
作为其参数,并应返回一个增强器数组。
例如:enhancers: (defaultEnhancers) => defaultEnhancers.prepend(offline)
将导致最终的设置为 [offline, applyMiddleware, devToolsExtension]
。
有关 enhancer
参数的工作方式以及默认添加的增强器列表的更多详细信息,请参见 getDefaultEnhancers
文档页面。
如果你不使用 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
的类型取决于其结果。
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 增强器被组合在一起