如何在Redux Middleware中使用增强后的Store?
可行,实现方法如下
Redux中间件初始化时拿到的store实例是增强前的——因为store增强器是在中间件链构建完成后,才对store进行扩展的。要让中间件访问到增强后的store上的API,有两种可靠的实现方式:
方法一:提前创建API,同时供中间件和增强器使用
直接在外部创建API实例,中间件直接引用这个实例,同时增强器把它挂载到store上。这种方式不需要依赖store对象传递API,逻辑更清晰。
修改后的代码:
import { createElement } from 'react' import { Provider, useDispatch } from 'react-redux' import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit' import { createRoot } from 'react-dom/client' function reducer(state, action){ console.debug("reducer...") return state } // 提前创建API实例 const api = {doSomething: () => console.debug("api.doSomething")} const apiMiddleware = (store) => (next) => (action) => { console.debug("apiMiddleware", api) // 直接使用提前创建的API api.doSomething() return next(action) } const storeEnhancer = (next) => { return (reducer, initialState) => { const the_store = {api, ...next(reducer, initialState)} console.debug("storeEnhancer", the_store) return the_store } } const store: any = configureStore({ reducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(apiMiddleware), enhancers: (defaultEnhancers) => [...defaultEnhancers, storeEnhancer], }) const ClickButton = () => { const dispatch = useDispatch() const onClick = () => dispatch({type: "action"}) return createElement("button", {onClick}, "clicky") } export const app = () => { const rootElement = document.getElementById("root") const root = createRoot(rootElement!) root.render(createElement(Provider, {store, children: createElement(ClickButton)})) return createElement("div", {}, "hello") }
方法二:利用RTK中间件的extraArgument传递API
通过getDefaultMiddleware的配置项传递额外参数,中间件可以直接从配置中拿到API:
// 提前创建API const api = {doSomething: () => console.debug("api.doSomething")} const apiMiddleware = (store) => (next) => (action) => { // 从extraArgument获取API const api = store.extraArgument console.debug("apiMiddleware", api) api.doSomething() return next(action) } const store: any = configureStore({ reducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ extraArgument: api // 传递API作为额外参数 }).concat(apiMiddleware), enhancers: (defaultEnhancers) => [...defaultEnhancers, storeEnhancer], })
原代码无法生效的原因
configureStore的执行顺序是:先构建中间件链,此时传入中间件的是未被增强的基础store;之后才会应用所有增强器扩展store。所以中间件里拿到的store对象不会包含增强器添加的api属性。
内容的提问来源于stack exchange,提问作者slaughter98
相关产品推荐
相关产品推荐

