React Query多mutateAsync执行顺序问题:如何串行执行后跳转
如何让两个mutateAsync串行执行并在都成功后跳转页面
问题场景
需求:依次执行两个mutateAsync,仅当两者都执行成功后跳转到指定页面。当前使用的代码如下:
const changeStatus = useChangeConsultStatus(); const editConsult = useEditConsulta(); async function onClickAttended() { await editConsult.mutateAsync({ consultID: consultID, consult: consultValues }); await changeStatus.mutateAsync({ consultID: consultID, status: "PENDING" }); console.log("Edit consult status:", editConsult.status ) //Edit consult status: idle console.log("Change status consult status:", changeStatus.status ) // Change status consult status: success If (editConsult.status === "success" && changeStatus.status === "success"){ router.push("/application"); } }
执行onClickAttended时,发现判断条件不生效——editConsult的状态仍为idle,无法触发跳转。
解决方案
核心问题分析
你遇到的问题并非mutateAsync并行执行,而是:
- 代码存在语法错误:
If应为小写if,直接导致判断逻辑无法运行; - React Query的
status状态更新是异步的,在await后立即读取状态,可能还未完成更新。
下面提供两种可靠的解决方式:
方案1:依赖await的成功反馈(推荐)
mutateAsync在请求成功时会返回结果,失败时会抛出异常。因此无需依赖status状态,直接用try/catch包裹两个异步操作,只要都顺利完成就跳转:
const changeStatus = useChangeConsultStatus(); const editConsult = useEditConsulta(); async function onClickAttended() { try { // 串行执行:先完成编辑请求 await editConsult.mutateAsync({ consultID: consultID, consult: consultValues }); // 编辑成功后,再执行状态变更请求 await changeStatus.mutateAsync({ consultID: consultID, status: "PENDING" }); // 两个请求都成功,执行跳转 router.push("/application"); } catch (error) { // 任意一个请求失败时,处理错误(如弹窗提示用户) console.error("操作失败:", error); } }
方案2:监听状态变更(适合需要状态联动的场景)
如果必须依赖status状态判断,需通过useEffect监听状态变化,确保React已完成状态更新后再执行跳转:
const changeStatus = useChangeConsultStatus(); const editConsult = useEditConsulta(); const router = useRouter(); async function onClickAttended() { await editConsult.mutateAsync({ consultID: consultID, consult: consultValues }); await changeStatus.mutateAsync({ consultID: consultID, status: "PENDING" }); } // 监听两个请求的状态,当都成功时跳转 useEffect(() => { if (editConsult.status === "success" && changeStatus.status === "success") { router.push("/application"); // 跳转后重置状态,避免重复触发 editConsult.reset(); changeStatus.reset(); } }, [editConsult.status, changeStatus.status, router]);
内容的提问来源于stack exchange,提问作者Miguel Angel Marroquin Jordan
相关产品推荐
相关产品推荐

