React如何在同一函数内实现axios PUT完成后再执行GET请求
问题根因
当前时序错乱的核心原因有两个:
update()内部的axios请求是异步逻辑,但你没有把异步状态向外暴露,调用update()后代码会立刻同步向下执行,根本不会等PUT请求返回- 点击事件里读取的
success是当前渲染闭包里的旧值,update内部setSuccess触发的状态更新要等下一次组件重渲染才会生效,你在同一个同步执行的点击回调里永远拿不到本次PUT请求返回的最新状态,自然没法准确判断什么时候该触发GET请求。
修复方案
核心思路是让Hook内的update、fetch方法返回内置的Promise实例,让调用方可以直接通过async/await控制执行顺序,不要依赖组件state传递异步时序。
第一步:修改Hook内部的两个异步方法,返回Promise
把axios请求的Promise直接return出去,同时把请求结果返回、错误抛出,方便外部逻辑直接处理:
const fetch = useCallback(() => { setLoading(true); // 返回axios Promise实例 return axios({ url: url, headers: foo, method: "get" }) .then((response) => { setLoading(false); setSuccess(response.status); setData(response.data); return response; }) .catch((error) => { setLoading(false); throw error; }); }, [setSuccess]); const update = useCallback(() => { setLoading(true); // 返回axios Promise实例 return axios({ url: url, headers: foo, method: "put", data: data, responseType: "json" }) .then((response) => { setLoading(false); setSuccess(response.status); return response; }) .catch((error) => { setLoading(false); throw error; }); }, [data]);
第二步:修改点击事件逻辑,用async/await严格控制执行顺序
不要在回调里读success state判断本次PUT的结果,直接await update()的返回值拿请求结果,确认PUT成功后再调用fetch(),后续的路由跳转、校验逻辑都按顺序写在await后面即可:
const OnClickHandler = async () => { try { // 等待PUT请求完成 const updateRes = await update(); if (updateRes.status === 200) { // PUT成功后再拉取最新数据 const latestDataRes = await fetch(); // 此处执行数据校验、路由跳转等后续逻辑,时序完全可控 } else { // 处理PUT返回非预期状态码的逻辑 } } catch (err) { // 统一捕获PUT/GET请求的异常,做错误提示等处理 } };
额外注意
不要用useEffect监听success状态变化来触发fetch,这种写法会导致所有把success改为200的场景(比如其他地方调用了fetch也会把success设为200)都触发多余的GET请求,链路逻辑分散很难维护,直接通过Promise控制异步链式调用是最清晰、最不容易出bug的方案。
内容的提问来源于stack exchange,提问作者ERLay
相关产品推荐
相关产品推荐

