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

React Router 6 Action中React Hook Form isSubmitting不更新及RTK异常

React Router 6 数据路由 + RHF + RTK Query 状态不更新问题解决

问题1:React Hook Form 的 formState.isSubmitting 不更新

原因

你用 React Router 的 useSubmit 替代了 RHF 原生提交逻辑,RHF 无法感知 useSubmit 触发的异步 Action 流程,因此不会自动更新 isSubmitting 状态。

解决办法

用 React Router 的 useNavigation 钩子同步加载状态,替代 RHF 自带的 isSubmitting:

import { useNavigation } from 'react-router-dom';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import yourSchema from './your-schema';

function YourForm() {
  const navigation = useNavigation();
  const { register, handleSubmit, formState: { errors } } = useForm({
    resolver: zodResolver(yourSchema),
  });

  // 用导航状态判断是否正在提交
  const isSubmitting = navigation.state === 'loading';

  const onSubmit = (data) => {
    useSubmit(data, { method: 'post' });
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {/* 表单字段 */}
      <button type="submit" disabled={isSubmitting}>
        {isSubmitting ? '提交中...' : '提交'}
      </button>
    </form>
  );
}

问题2:RTK Query useCreateItemMutation 的 isLoading/error 无变化

原因

你在 Action 里用 store.dispatch 手动触发 mutation,而 useCreateItemMutation 返回的状态仅追踪该钩子自身的 mutate 函数发起的请求,手动 dispatch 的 mutation 不会更新钩子状态。

解决办法

分两种场景处理:

场景1:无需依赖 React Router Action,直接在组件处理提交

直接用 RTK Query 钩子返回的 mutate 函数,RHF 会自动管理 isSubmitting,同时钩子的 isLoading/error 也会正常更新:

import { useNavigate } from 'react-router-dom';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { useCreateItemMutation } from './api-slice';
import yourSchema from './your-schema';

function YourForm() {
  const navigate = useNavigate();
  const [createItem, { isLoading, error }] = useCreateItemMutation();
  const { register, handleSubmit, formState: { errors } } = useForm({
    resolver: zodResolver(yourSchema),
  });

  const onSubmit = async (data) => {
    try {
      await createItem(data).unwrap();
      navigate('/items');
    } catch (err) {
      // 处理错误,比如存入 RHF 的 setError
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {/* 表单字段 */}
      {error && <div className="error">{error.message}</div>}
      <button type="submit" disabled={isLoading}>
        {isLoading ? '提交中...' : '提交'}
      </button>
    </form>
  );
}

场景2:必须用 React Router Action 处理提交

组件里改用 React Router 的 useActionData 获取错误,用 useNavigation 判断加载状态,Action 里保持原有 dispatch 逻辑:

// Action 函数示例
import { redirect } from 'react-router-dom';
import { store } from './store';
import { createItemMutation } from './api-slice';

export async function createItemAction({ request }) {
  const formData = await request.formData();
  const data = Object.fromEntries(formData);
  try {
    await store.dispatch(createItemMutation(data)).unwrap();
    return redirect('/items');
  } catch (err) {
    // 返回错误信息给组件
    return { error: err.message };
  }
}
// 组件示例
import { useNavigation, useActionData, useSubmit } from 'react-router-dom';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import yourSchema from './your-schema';

function YourForm() {
  const navigation = useNavigation();
  const actionData = useActionData();
  const submit = useSubmit();
  const { register, handleSubmit, formState: { errors } } = useForm({
    resolver: zodResolver(yourSchema),
  });

  const isSubmitting = navigation.state === 'loading';
  const submitError = actionData?.error;

  const onSubmit = (data) => {
    submit(data, { method: 'post' });
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {/* 表单字段 */}
      {submitError && <div className="error">{submitError}</div>}
      <button type="submit" disabled={isSubmitting}>
        {isSubmitting ? '提交中...' : '提交'}
      </button>
    </form>
  );
}

注意事项

  • 避免混合两种提交模式:要么用 RHF + RTK Query mutate + 手动跳转,要么用 React Router useSubmit + Action + 导航状态,混合会导致状态不同步。
  • 确保 Action 已正确配置到对应路由的 action 属性中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 04:52:06