You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redux迁移至React Context API+useReducer时WebSocket中间件绑定问题

问题根因

  • 你当前实现的useReducerWithMiddleware调用中间件的逻辑不符合Redux中间件的执行规则,核心错误有2个:
    1. 执行顺序颠倒:你先调用了原生dispatch把action提交给reducer执行完成后,才把返回值传给中间件,等于中间件完全没拦截到提交到reducer之前的action
    2. 参数不匹配:你用的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 11:36:04