如何处理Axios延迟响应导致React Query的useMutation提前触发onSuccess?
问题解决:useMutation onSuccess提前触发导致res.data undefined
你的问题出在UserLogin函数的实现上——虽然它标了async,但内部的setTimeout并没有让函数真正等待异步操作完成:
async函数如果没有返回pending状态的Promise,会直接返回一个resolved的Promise,值为undefined- 你里面的
setTimeout回调是独立的async函数,和外部的UserLogin执行流程无关,所以UserLogin执行到setTimeout后就直接结束了,useMutation误以为请求已经完成,立刻触发onSuccess,而此时axios请求还在5秒延迟中,自然拿不到数据。
修复步骤
1. 修正UserLogin函数,返回正确的Promise
把setTimeout包装成Promise,确保函数会等待5秒后axios请求完成再返回结果:
async function UserLogin(user) { console.log("USER LOGIN API CALLED"); console.log(user); // 用Promise包裹setTimeout,让async函数等待异步操作完成 return new Promise((resolve) => { setTimeout(async () => { const response = await axios.post("/Auth/Login", user); resolve(response); }, 5000); }); }
或者更简洁的写法(利用axios.post本身返回Promise的特性):
function UserLogin(user) { console.log("USER LOGIN API CALLED"); console.log(user); return new Promise((resolve) => { setTimeout(() => { resolve(axios.post("/Auth/Login", user)); }, 5000); }); }
2. 简化useMutation的mutationFn
修正后的UserLogin已经返回Promise,所以mutationFn不需要额外的async/await,直接传入即可:
export const apiAuthLogin = () => { return useMutation({ mutationKey: ["login"], mutationFn: UserLogin, onSuccess: (res) => { console.log("useMutation Login Success"); console.log(res.data); // 现在能正常获取响应数据了 localStorage.setItem("Token", res.data); }, onError: (err) => { console.log('useMutation Login Failed') console.log(err) } }); };
原理说明
修改后,UserLogin会返回一个pending状态的Promise,直到5秒后axios请求完成才会resolve响应结果。useMutation会等待这个Promise完成后再触发onSuccess,此时res就是axios的响应对象,res.data就能拿到正确的返回值了。
内容的提问来源于stack exchange,提问作者Liam neesan
相关产品推荐
相关产品推荐

