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

React Router v6.4+ Data API:Loader失败重试不显示错误实现方案

在React Router 6.21.1 Data API中实现Loader的错误重试与自动重新验证

需求回顾

你的看板页面需要24小时持续展示,每5分钟重新拉取数据;遇到请求失败时最多重试5次(保障至少30分钟可用),之前用useEffect实现了该逻辑,现在要迁移到React Router的Loader中。

实现方案

1. 封装带状态跟踪的Loader函数

利用sessionStorage缓存数据和重试次数(页面会话期间有效,符合24小时展示的需求),在Loader中处理请求、重试计数和缓存逻辑:

async function fetchDashboard() {
  const cacheKey = 'dashboard-data';
  const retryKey = 'dashboard-retry-count';
  // 从sessionStorage读取重试次数和缓存数据
  let retryCount = parseInt(sessionStorage.getItem(retryKey)) || 0;
  const cachedData = sessionStorage.getItem(cacheKey);

  try {
    const response = await axios.get('dashboard');
    // 请求成功:更新缓存并重置重试计数
    sessionStorage.setItem(cacheKey, JSON.stringify(response.data));
    sessionStorage.setItem(retryKey, '0');
    return response.data;
  } catch (error) {
    if (retryCount < 5) {
      // 未达重试上限:更新计数,返回缓存数据(如果有)
      sessionStorage.setItem(retryKey, (retryCount + 1).toString());
      if (cachedData) {
        return JSON.parse(cachedData);
      }
      // 首次加载无缓存时,直接抛出错误
      throw error;
    } else {
      // 重试次数用尽:重置计数并抛出错误,触发ErrorElement
      sessionStorage.setItem(retryKey, '0');
      throw error;
    }
  }
}

2. 配置路由自动重新验证

在路由配置中添加revalidate选项,设置为300秒(5分钟),让React Router自动定时重新执行Loader:

const routes = [
    {
        element: <RootWrapper/>,
        errorElement: <ErrorWrapper/>,
        children: [
            {path: "/login?", element: <LoginWrapper/>},
            {path: "/logout", element: <Logout/>},
            {
                id: "AuthenticatedRoot",
                element: <AuthenticatedRoot/>,
                children: [
                    // ...
                    {
                        path: "/dashboard", 
                        element: <Dashboard/>, 
                        loader: fetchDashboard,
                        revalidate: 300 // 每5分钟自动重新验证
                    },
                ]
            }
        ]
]

3. 组件内可选手动触发重新验证

如果需要更精确的控制(比如组件挂载后立即启动定时),可以在Dashboard组件中用useRevalidator手动触发:

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

function Dashboard() {
  const data = useLoaderData();
  const { revalidate } = useRevalidator();

  // 组件挂载后每5分钟触发一次重新验证
  useEffect(() => {
    const interval = setInterval(() => {
      revalidate();
    }, 5 * 60 * 1000);

    return () => clearInterval(interval);
  }, [revalidate]);

  return (
    <div>
      {/* 渲染看板内容 */}
    </div>
  );
}

4. 错误兜底处理

当重试次数用尽后,Loader抛出的错误会触发上级的errorElement,可以在ErrorWrapper中添加手动重试按钮:

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

function ErrorWrapper() {
  const error = useRouteError();
  const { revalidate } = useRevalidator();

  return (
    <div className="error-container">
      <h2>数据加载失败</h2>
      <p>{error.message}</p>
      <button onClick={() => revalidate()}>尝试重新加载</button>
    </div>
  );
}

逻辑说明

  • 缓存机制:请求成功时更新缓存,失败时返回缓存数据,确保页面始终有内容展示。
  • 重试计数:用sessionStorage跟踪重试次数,每次失败递增,成功或用尽次数后重置。
  • 自动重新验证:通过路由的revalidate配置实现每5分钟自动拉取数据,无需手动维护定时器(组件内的定时器为可选增强)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 19:03:25