createDynamicMiddleware
概要
ストアの初期化後にミドルウェアをディスパッチチェーンに追加できる「メタミドルウェア」です。
インスタンスの作成
import { createDynamicMiddleware, configureStore } from '@reduxjs/toolkit'
const dynamicMiddleware = createDynamicMiddleware()
const store = configureStore({
reducer: {
todos: todosReducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().prepend(dynamicMiddleware.middleware),
})
createDynamicMiddleware
には、2 つの型パラメータ `State` と `Dispatch` を渡すことができます。
これらは、ミドルウェアを受け取るメソッドで使用され、提供されたミドルウェアが提供された型と互換性があることを保証します.
const dynamicMiddleware = createDynamicMiddleware<State, Dispatch>()
ただし、これらの値がストアから派生している場合 (そうあるべきですが)、循環型の依存関係が形成されます。
そのため、`addMiddleware`、`withMiddleware`、`createDispatchWithMiddlewareHook` に付属の `withTypes` ヘルパーを使用することをお勧めします.
import { createDynamicMiddleware } from '@reduxjs/toolkit/react'
import type { RootState, AppDispatch } from './store'
const dynamicMiddleware = createDynamicMiddleware()
const {
middleware,
addMiddleware,
withMiddleware,
createDispatchWithMiddlewareHook,
} = dynamicMiddleware
interface MiddlewareApiConfig {
state: RootState
dispatch: AppDispatch
}
export const addAppMiddleware = addMiddleware.withTypes<MiddlewareApiConfig>()
export const withAppMiddleware = withMiddleware.withTypes<MiddlewareApiConfig>()
export const createAppDispatchWithMiddlewareHook =
createDispatchWithMiddlewareHook.withTypes<MiddlewareApiConfig>()
export default middleware
動的ミドルウェアインスタンス
`createDynamicMiddleware` から返される「動的ミドルウェアインスタンス」は、`createListenerMiddleware` によって生成されるオブジェクトと似たオブジェクトです。インスタンスオブジェクトは実際の Redux ミドルウェア自体では*ありません*。 むしろ、ミドルウェアとチェーンにミドルウェアを追加するために使用されるいくつかのインスタンスメソッドが含まれています.
export type DynamicMiddlewareInstance<
State = unknown,
Dispatch extends ReduxDispatch<UnknownAction> = ReduxDispatch<UnknownAction>,
> = {
middleware: DynamicMiddleware<State, Dispatch>
addMiddleware: AddMiddleware<State, Dispatch>
withMiddleware: WithMiddleware<State, Dispatch>
}
`middleware`
Redux ストアに追加するラッパーミドルウェアインスタンスです.
これをミドルウェアチェーンのどこにでも配置できますが、このインスタンスに挿入するすべてのミドルウェアはこの位置に含まれることに注意してください.
`addMiddleware`
インスタンスにミドルウェアのセットを挿入します.
addMiddleware(logger, listenerMiddleware.instance)
ミドルウェアは関数参照によって比較され、それぞれはチェーンに一度だけ追加されます.
ミドルウェアは ES6 マップに格納されるため、ディスパッチ中は挿入順に呼び出されます.
`withMiddleware`
ミドルウェアのセットを受け取り、アクションを作成します. ディスパッチされると、ミドルウェアを挿入し、追加された拡張を認識するように型付けされた `dispatch` のバージョンを返します.
const listenerDispatch = store.dispatch(
withMiddleware(listenerMiddleware.middleware),
)
const unsubscribe = listenerDispatch(addListener({ type, effect }))
Reactとの統合
React 固有のエントリポイント ( `@reduxjs/toolkit/react`) からインポートすると、`createDynamicMiddleware` を呼び出した結果には追加のメソッドが添付されます.
これらは `react-redux` がインストールされていることに依存します.
interface ReactDynamicMiddlewareInstance<
State = any,
Dispatch extends ReduxDispatch<UnknownAction> = ReduxDispatch<UnknownAction>,
> extends DynamicMiddlewareInstance<State, Dispatch> {
createDispatchWithMiddlewareHook: CreateDispatchWithMiddlewareHook<
State,
Dispatch
>
createDispatchWithMiddlewareHookFactory: (
context?: Context<
ReactReduxContextValue<State, ActionFromDispatch<Dispatch>>
>,
) => CreateDispatchWithMiddlewareHook<State, Dispatch>
}
`createDispatchWithMiddlewareHook`
ミドルウェアのセットを受け取り、提供されたミドルウェアからの拡張を含むように型付けされた `dispatch` を返す `useDispatch` フックを返します.
const useListenerDispatch = createDispatchWithMiddlewareHook(
listenerInstance.middleware,
)
const Component = () => {
const listenerDispatch = useListenerDispatch()
useEffect(() => {
const unsubscribe = listenerDispatch(addListener({ type, effect }))
return () => unsubscribe()
}, [dispatch])
}
ミドルウェアは、`useDispatch` フックが使用されるときではなく、`createDispatchWithMiddlewareHook` が呼び出されるときに挿入されます.
`createDispatchWithMiddlewareHookFactory`
React コンテキストインスタンスを受け取り、そのコンテキストを使用するように構築された `createDispatchWithMiddlewareHook` を返します.
const createDispatchWithMiddlewareHook =
createDispatchWithMiddlewareHookFactory(context)
React Redux でカスタムコンテキストを使用している場合に便利です.