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

React Router v7加载数据过慢时如何显示LoadingIndicator组件?

解决方案

方案1:全局加载提示(最简单)

直接给RouterProvider添加fallback属性,当任何loader处于加载状态时,会显示你指定的加载组件:

  1. 先创建你的LoadingIndicator组件(示例):
// components/LoadingIndicator.jsx
function LoadingIndicator() {
  return <div style={{ textAlign: 'center', padding: '2rem' }}>加载中...</div>;
}

export default LoadingIndicator;
  1. 修改main.jsx,导入并配置fallback:
import React from "react";
import ReactDOM from "react-dom/client";
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import Posts, { loader as postsLoader } from "./routes/Posts";
import NewPost, { action as newPostAction } from "./routes/NewPost";
import RootLayout from "./routes/RootLayout";
import LoadingIndicator from "./components/LoadingIndicator"; // 加载组件
import "./index.css";

const router = createBrowserRouter([
  {
    path: "/",
    element: <RootLayout />,
    children: [
      {
        path: "/",
        element: <Posts />,
        loader: postsLoader,
        children: [
          { path: "create-post", element: <NewPost />, action: newPostAction },
        ],
      },
    ],
  },
]);

const rootElement = document.getElementById("root");

ReactDOM.createRoot(rootElement).render(
  <React.StrictMode>
    {/* 添加fallback属性 */}
    <RouterProvider router={router} fallback={<LoadingIndicator />} />
  </React.StrictMode>
);

这个方案会在loader加载期间,将页面内容替换为加载组件,适合简单场景。

方案2:局部加载提示(保留RootLayout)

如果希望加载时仍显示RootLayout(比如顶部导航栏),可以调整路由结构并使用useNavigation钩子判断加载状态:

  1. 调整路由配置,将子路由改为index路由,让父路由RootLayout优先渲染:
// main.jsx中的router配置
const router = createBrowserRouter([
  {
    path: "/",
    element: <RootLayout />,
    children: [
      {
        index: true, // 替代path: "/"
        element: <Posts />,
        loader: postsLoader,
        children: [
          { path: "create-post", element: <NewPost />, action: newPostAction },
        ],
      },
    ],
  },
]);
  1. 在RootLayout中判断加载状态,保留导航栏的同时显示加载提示:
// routes/RootLayout.jsx
import { Outlet, useNavigation } from "react-router-dom";
import MainHeader from "../components/MainHeader";
import LoadingIndicator from "../components/LoadingIndicator";

function RootLayout() {
  const navigation = useNavigation();
  const isLoading = navigation.state === "loading";

  return (
    <>
      <MainHeader />
      {/* 加载时显示LoadingIndicator,否则渲染子路由内容 */}
      {isLoading ? <LoadingIndicator /> : <Outlet />}
    </>
  );
}

export default RootLayout;

也可以仅给帖子列表区域添加加载提示:

// routes/Posts.jsx
import PostsList from "../components/PostsList";
import { Outlet, useNavigation } from "react-router-dom";
import LoadingIndicator from "../components/LoadingIndicator";

function Posts() {
  const navigation = useNavigation();
  const isLoading = navigation.state === "loading";

  return (
    <>
      <Outlet />
      <main>
        {isLoading ? <LoadingIndicator /> : <PostsList />}
      </main>
    </>
  );
}

export default Posts;

原理说明

  • RouterProvider的fallback基于React Suspense实现,在路由loader/action执行期间显示备用内容。
  • useNavigation钩子可获取当前路由的导航状态,navigation.state === "loading"表示正在执行loader或action。
  • 使用index路由能让父路由组件优先渲染,避免整个页面空白。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 13:53:14