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

React Router v6结合Formik提交表单后如何重新验证Loader?

解决React Router v6 Action完成后Loader不重新验证的问题

核心问题分析

你遇到的问题涉及两个关键层面:一是React Router是否触发Loader重新执行,二是RTK Query的缓存是否会返回旧数据。即使Loader重新执行,若RTK Query缓存未失效,仍会显示旧数据;反之,若Loader未触发,自然无法获取新数据。


解决方案步骤

1. 移除Action中的Redirect,让React Router自动触发Loader

React Router默认在Action执行完成且未返回redirect时,会自动重新运行当前路由的Loader。你当前返回redirect到同一页面,虽理论上也会触发,但直接返回null更简洁,可避免潜在的路由缓存问题。

修改路由Action:

{
  path: 'edit',
  element: <HedrEdit />,
  loader: args =>
    baseLoader(
      args,
      enhancedHedrApi.endpoints.getHedrById,
      'hedrId'
    ),
  action: async ({ request, params, dispatch }) => { // 新增dispatch参数
    const formData = await request.formData();
    const values = Object.fromEntries(formData);
    const data: PutHedrByIdApiArg = {
      id: Number(params.hedrId),
      hedr: values,
    };
    await editFetch(
      enhancedHedrApi.endpoints.putHedrById,
      data
    );
    // 失效Hedr相关缓存标签(需匹配你的RTK Query标签配置)
    dispatch(enhancedHedrApi.util.invalidateTags(['Hedr']));
    // 返回null,触发React Router自动重新验证Loader
    return null;
  },
}

2. 失效RTK Query缓存确保获取最新数据

RTK Query默认会缓存请求结果,因此即使Loader重新执行,也可能返回旧数据。在PUT请求成功后,调用invalidateTags强制失效对应缓存,这样后续的GET请求会拉取最新数据。

注意:['Hedr']是示例标签,需替换为你在RTK Query定义getHedrById时设置的providesTags值,比如:

// 示例RTK Query endpoint定义
getHedrById: builder.query({
  query: (id) => `/hedr/${id}`,
  providesTags: (result) => [{ type: 'Hedr', id: result.id }]
})

此时失效标签应改为[{ type: 'Hedr', id: Number(params.hedrId) }],更精准地失效单条数据缓存。

3. 确保Loader中的RTK Query请求能重新获取数据

检查你的baseLoader实现,确保它正确发起RTK Query请求且未设置阻止重新请求的缓存策略。例如:

async function baseLoader(args, endpoint, paramKey) {
  const param = args.params[paramKey];
  const result = await args.dispatch(endpoint.initiate(param));
  if (result.isError) {
    throw result.error;
  }
  return result.data;
}

由于我们已经失效了缓存,initiate会自动发起新请求,无需额外添加forceRefetch: true。

4. 备选:手动用useRevalidator触发重新验证

如果上述方法仍不生效,可在组件中结合useRevalidator和useNavigation,监听表单提交状态,手动触发Loader重新执行:

import { useRevalidator, useNavigation } from 'react-router-dom';
import { useEffect } from 'react';

const HedrEdit = () => {
  const { revalidate } = useRevalidator();
  const navigation = useNavigation();
  const submit = useSubmit();

  // 当提交状态从submitting变为idle时,触发重新验证
  useEffect(() => {
    if (navigation.state === 'idle') {
      revalidate();
    }
  }, [navigation.state, revalidate]);

  const formikState = useFormik<HedrModel>({
    initialValues: {
      name: data?.name || '',
    },
    validateOnChange: false,
    validateOnBlur: false,
    enableReinitialize: true,

    onSubmit: (values) => {
      const submitData = { ...values };
      submit(submitData, { method: 'put' });
    },
  });

  // ... 表单代码
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 07:18:11