为何使用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; }
关键修改点
- 剥离异步逻辑:把原reducer里的axios请求移到
useEffect的get函数中,这里可以放心用async/await处理异步操作。 - 同步reducer:reducer只负责接收action携带的数据,同步更新state,不再处理任何异步操作。
- 正确更新state:请求完成后通过dispatch把数据传给reducer,最终
requests会是实际的响应数据,而非Promise。 - 补全依赖项:给
useEffect添全所有用到的外部变量,避免出现意外的执行时机问题。
内容的提问来源于stack exchange,提问作者Muathcs
相关产品推荐
相关产品推荐

