运行时如何向已初始化的createListenerMiddleware注入外部API?
解决方案:在Redux Listener Middleware中动态注入外部API
Redux Toolkit的createListenerMiddleware本身没有直接提供类似Redux Saga setContext的现成API,但可以通过以下两种方式实现动态注入外部依赖:
方法1:扩展Listener Middleware实例对象
Listener Middleware创建后会返回包含middleware和startListening的对象,你可以在外部API初始化完成后,直接给这个实例添加自定义属性来注入API:
// 提前在模块级别创建listener middleware(确保是单例) const listenerMiddleware = createListenerMiddleware(); // 初始化store时传入该middleware const store = configureStore({ reducer: rootReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware().prepend(listenerMiddleware.middleware), }); // 外部初始化函数中注入API function initApp(externalApi) { listenerMiddleware.externalApi = externalApi; } // 在listener逻辑中使用注入的API listenerMiddleware.startListening({ actionCreator: fetchDataAction, effect: async (action, listenerApi) => { const response = await listenerMiddleware.externalApi.getResource(action.payload.id); listenerApi.dispatch(receiveDataAction(response)); }, });
方法2:使用自定义依赖容器
如果需要更灵活的依赖管理,可以创建一个全局容器,初始化时注入API,listener逻辑直接从容器中读取:
// 定义依赖容器 const appDependencies = { externalApi: null, }; // 外部初始化函数注入API function initApp(externalApi) { appDependencies.externalApi = externalApi; } // 创建listener middleware并使用容器中的API const listenerMiddleware = createListenerMiddleware(); listenerMiddleware.startListening({ actionCreator: submitFormAction, effect: async (action, listenerApi) => { if (!appDependencies.externalApi) { throw new Error('外部API未完成初始化'); } await appDependencies.externalApi.submitForm(action.payload); listenerApi.dispatch(formSubmittedAction()); }, }); // 初始化store...
关于startListening访问问题的说明
你之前遇到无法访问startListening的情况,核心原因是在初始化函数内重新创建了新的listener middleware实例,而非引用store初始化时使用的那个单例。必须保证listener middleware是全局/模块级别的单例,在store初始化前创建,后续所有操作都复用同一个实例,才能正常访问startListening和注入的API。
内容的提问来源于stack exchange,提问作者Vitalii Kravchyk
相关产品推荐
相关产品推荐

