Redux迁移至React Context API+useReducer时WebSocket中间件绑定问题
问题根因
- 你当前实现的
useReducerWithMiddleware调用中间件的逻辑不符合Redux中间件的执行规则,核心错误有2个:- 执行顺序颠倒:你先调用了原生
dispatch把action提交给reducer执行完成后,才把返回值传给中间件,等于中间件完全没拦截到提交到reducer之前的action - 参数不匹配:你用的
socketFunction是标准Redux三层柯里化中间件格式(store => next => action),但你调用时只传了1个参数,没有完成柯里化的逐层调用,所以中间件逻辑根本不会执行
- 执行顺序颠倒:你先调用了原生
修复方案
第一步:重写useReducerWithMiddleware,适配Redux格式中间件
import { useReducer, useMemo } from "react"; export const useReducerWithMiddleware = (reducer, initialState, middleware = []) => { const [state, baseDispatch] = useReducer(reducer, initialState); // 构造类似Redux的store对象给中间件使用 const store = useMemo(() => ({ getState: () => state, dispatch: (action) => dispatch(action) }), [state]); // 兼容单中间件和中间件数组两种传入格式 const middlewareList = Array.isArray(middleware) ? middleware : [middleware]; // 逐层执行柯里化的中间件,组装增强dispatch链 const chain = middlewareList.map(mw => mw(store)); const enhancedDispatch = compose(...chain)(baseDispatch); // 处理thunk逻辑,thunk内部调用的dispatch也会走中间件链路 const dispatch = action => { if (typeof action === "function") { return action(dispatch, store.getState); } return enhancedDispatch(action); }; return [state, dispatch]; }; // 实现和Redux逻辑一致的compose工具函数,用来组合中间件 function compose(...funcs) { if (funcs.length === 0) { return arg => arg } if (funcs.length === 1) { return funcs[0] } return funcs.reduce((a, b) => (...args) => a(b(...args))) }
第二步:保持现有调用逻辑不变
你之前写的Provider传参、socket中间件代码都不需要修改,修复后socketFunction的断点会正常触发,所有action都会先经过中间件处理再提交给reducer执行。
内容的提问来源于stack exchange,提问作者Sinan Yaman
相关产品推荐
相关产品推荐

