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

为何使用Async后,Reducer仍返回Promise?

问题原因及解决方法

核心问题:reducer不能是异步函数

React的useReducer要求reducer必须是纯同步函数,它的作用是根据action同步计算新的state。你把reducer定义成了async function,这类函数本身执行后就会返回Promise——哪怕你在里面用了await,最终返回给useReducer的依然是Promise对象,这直接导致你的requests state变成了Promise,而非实际的接口响应数据。

正确实现:异步操作移到reducer外部

应该把axios请求放在useEffect的函数里,等请求完成拿到数据后,再dispatch一个携带数据的action,让reducer同步更新state。

修改后的代码

type HttpMethod = "get" | "post" | "put";

const initialState: any = [];
// 改为纯同步的reducer,只负责state更新逻辑
function reducer(state: any, action: any) {
  switch (action.type) {
    case "GET_SUCCESS":
      return action.payload.data;
    case "GET_ERROR":
      console.error(action.payload.error);
      return state; // 出错时保留原有state,也可自定义错误状态
    default:
      return state;
  }
}

export function useGlobalAxios(method: HttpMethod, dataToFetch: string, params?: unknown) {
  const [requests, dispatch] = useReducer(reducer, initialState);

  useEffect(() => {
    // 这里的get函数可以是async,正常处理异步请求
    async function get() {
      if (method !== "get") return;
      try {
        const response = await axios.get(
          `http://localhost:3001/${dataToFetch}`,
          { params: { data: params } }
        );
        // 请求成功后,dispatch同步action更新state
        dispatch({ type: "GET_SUCCESS", payload: { data: response.data } });
      } catch (error) {
        dispatch({ type: "GET_ERROR", payload: { error } });
      }
    }

    get();
  }, [dataToFetch, method, params]); // 补全依赖项,确保触发时机正确

  return requests;
}

关键修改点

  1. 剥离异步逻辑:把原reducer里的axios请求移到useEffect的get函数中,这里可以放心用async/await处理异步操作。
  2. 同步reducer:reducer只负责接收action携带的数据,同步更新state,不再处理任何异步操作。
  3. 正确更新state:请求完成后通过dispatch把数据传给reducer,最终requests会是实际的响应数据,而非Promise。
  4. 补全依赖项:给useEffect添全所有用到的外部变量,避免出现意外的执行时机问题。

内容的提问来源于stack exchange,提问作者Muathcs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 03:15:19