跳到主要内容

 

getDefaultMiddleware

返回一个包含默认中间件列表的数组。

预期用法

默认情况下,configureStore 会自动向 Redux store 设置中添加一些中间件。

const store = configureStore({
reducer: rootReducer,
})

// Store 已添加中间件,因为中间件列表没有被自定义

如果你想自定义中间件列表,你可以向 configureStore 提供一个中间件函数的数组:

const store = configureStore({
reducer: rootReducer,
middleware: () => new Tuple(thunk, logger),
})

// Store 明确地应用了 thunk 和 logger 中间件

然而,当你提供 middleware 选项时,你需要负责定义你想添加到 store 的所有中间件。configureStore 不会添加你列出的任何额外中间件。

getDefaultMiddleware 在你想添加一些自定义中间件,但也仍然想添加默认中间件时非常有用:

import { configureStore } from '@reduxjs/toolkit'

import logger from 'redux-logger'

import rootReducer from './reducer'

const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger),
})

// Store 添加了所有默认的中间件,_以及_ logger 中间件

优先使用返回的 Tuple 的链式 .concat(...).prepend(...) 方法,而不是数组扩展运算符,因为后者在某些情况下可能会丢失有价值的 TS 类型信息。

包含的默认中间件

开发

Redux Toolkit 的目标之一是提供有见地的默认值并防止常见错误。作为其中的一部分,getDefaultMiddleware 包含一些只在你的应用的开发构建中添加的中间件,以提供对三个常见问题的运行时检查:

  • 不可变性检查中间件:深度比较状态值的变化。它可以在调度期间检测到 reducer 中的变化,也可以在调度之间(如在组件或选择器中)检测到变化。当检测到变化时,它会抛出一个错误,并指出在状态树中检测到变化值的键路径。(从 redux-immutable-state-invariant 分支出来。)

  • 可序列化性检查中间件:专门为 Redux Toolkit 创建的自定义中间件。与 immutable-state-invariant 的概念类似,但深度检查你的状态树和你的动作是否包含非序列化值,如函数、Promise、Symbol 和其他非普通 JS 数据值。当检测到非序列化值时,会打印一个控制台错误,并显示检测到非序列化值的键路径。

  • 动作创建者检查中间件:另一个专门为 Redux Toolkit 创建的自定义中间件。识别出动作创建者被错误地调度而没有被调用,并向控制台警告动作类型。

除了这些开发工具中间件,它还默认添加了 redux-thunk,因为 thunk 是 Redux 推荐的基本副作用中间件。

目前,返回值是:

const middleware = [
actionCreatorInvariant,
immutableStateInvariant,
thunk,
serializableStateInvariant,
]

生产

目前,返回值是:

const middleware = [thunk]

自定义包含的中间件

getDefaultMiddleware 接受一个选项对象,允许以两种方式自定义每个中间件:

  • 通过为其对应的字段传递 false,可以从结果数组中排除每个中间件
  • 通过为其对应的字段传递匹配的选项对象,可以自定义每个中间件的选项

这个例子显示了排除可序列化状态检查中间件,并为 thunk 中间件的 "extra argument" 传递一个特定值:

// 文件: reducer.ts noEmit

export default function rootReducer(state = {}, action: any) {
return state
}

// 文件: api.ts noEmit

export declare const myCustomApiService: any

// 文件: store.ts

import { configureStore } from '@reduxjs/toolkit'
import rootReducer from './reducer'
import { myCustomApiService } from './api'

const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
thunk: {
extraArgument: myCustomApiService,
},
serializableCheck: false,
}),
})

API 参考

interface ThunkOptions<E = any> {
extraArgument: E
}

interface ImmutableStateInvariantMiddlewareOptions {
// 见 "不可变性中间件" 页面的定义
}

interface SerializableStateInvariantMiddlewareOptions {
// 见 "可序列化性中间件" 页面的定义
}

interface ActionCreatorInvariantMiddlewareOptions {
// 见 "动作创建者中间件" 页面的定义
}

interface GetDefaultMiddlewareOptions {
thunk?: boolean | ThunkOptions
immutableCheck?: boolean | ImmutableStateInvariantMiddlewareOptions
serializableCheck?: boolean | SerializableStateInvariantMiddlewareOptions
actionCreatorCheck?: boolean | ActionCreatorInvariantMiddlewareOptions
}

function getDefaultMiddleware<S = any>(
options: GetDefaultMiddlewareOptions = {},
): Middleware<{}, S>[]