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

RTK Query提交mutation后首次isSuccess为false问题排查

问题根因

这是React闭包与状态更新机制导致的正常现象,不是RTK Query的bug:

  • isSuccess是mutation hook返回的响应式状态,值的更新依赖组件重渲染
  • 提交回调onSubmit中捕获的isSuccess是函数创建时的闭包旧值。await postCredentials()执行完成后,虽然RTK Query内部已经标记请求成功,但这个状态变更需要等待组件重渲染才能同步到最新值,当前正在执行的onSubmit回调里拿到的永远是提交前的初始值false
  • 第二次点击提交时,组件已经因第一次请求成功完成重渲染,新的onSubmit闭包捕获到了更新后的isSuccess = true,才会打印出预期结果。
正确写法

不要在提交回调中依赖闭包捕获的isSuccess判断请求结果。mutation触发函数postCredentials在await后本身就会返回请求的终态结果,直接判断该返回值即可:

const Login = () => {
  const {
    register,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm();
  const [postCredentials] = useLoginMutation();
  const dispatch = useDispatch();

  const onSubmit = async (data: any) => {
    try {
      // 调用unwrap()拆解结果:请求成功时返回响应数据,失败时抛出异常
      const response = await postCredentials({
        username: data.username,
        password: data.password,
      }).unwrap();
      // 代码走到此处即代表请求成功,可直接执行后续逻辑
      dispatch(setUserStatus({ isLoggedIn: true }));
      console.log('登录请求成功', response);
    } catch (error) {
      // 此处处理请求失败逻辑
      console.error('登录请求失败', error);
    }
  };

  return (
    // 原有表单渲染逻辑
    <form onSubmit={handleSubmit(onSubmit)}>{/* 表单项 */}</form>
  )
}

可选替代方案

如果需要基于isSuccess状态执行全局副作用,可以通过useEffect监听状态变化,不要在提交回调中读取闭包值:

const [postCredentials, { isSuccess }] = useLoginMutation();
const dispatch = useDispatch();

useEffect(() => {
  if (isSuccess) {
    dispatch(setUserStatus({ isLoggedIn: true }));
  }
}, [isSuccess, dispatch]);

注意:该方案需要额外处理多次提交导致的副作用重复触发问题,建议优先使用前一种直接判断trigger返回值的写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 12:33:08