如何在 react-router-dom v6.4 中使用 RouterProvider 和 Suspense?

10

这是我拥有的两个组件,我的问题是在哪里放置 <React.Suspense> 组件以根据需要加载路由?

Navagtion/index.jsx

import React from "react";
import {
  RouterProvider,
  createBrowserRouter,
  createRoutesFromElements
} from "react-router-dom";
import Root from "./Root";

const router = createBrowserRouter(createRoutesFromElements(Root));

const Navigation = () => {
  return <RouterProvider router={router} />;
};

export default Navigation;

Root.jsx

import React from "react";
import { Route } from "react-router-dom";

const PublicLayout = React.lazy(() => "../Layouts/PublicLayout");
const PrivateLayout = React.lazy(() => "../Layouts/PrivateLayout");

const Index = React.lazy(() => "../Pages");
const Welcome = React.lazy(() => "../Pages/Welcome");
const Login = React.lazy(() => "../Pages/Login");
const Register = React.lazy(() => "../Pages/Register");

const Root = (
  <Route path="/" element={<Index />}>
    <Route element={<PublicLayout />}>
      <Route path="/login" element={<Login />} />
      <Route path="/register" element={<Register />} />
    </Route>

    <Route element={<PrivateLayout />}>
      <Route path="/welcome" element={<Welcome />} />
    </Route>
  </Route>
);

export default Root;

我该如何在组件内部实现路由懒加载?在哪里将所有路由包装在Suspense中?

我该如何在组件内部实现路由懒加载?在哪里将所有路由包装在Suspense中?

2个回答

6

remix-run/react-router demo 展示了将每个懒加载导入的组件包装在它们自己的 React.Suspense 组件中:

import React from "react";
import { Route } from "react-router-dom";

const PublicLayout = React.lazy(() => "../Layouts/PublicLayout");
const PrivateLayout = React.lazy(() => "../Layouts/PrivateLayout");

const Index = React.lazy(() => "../Pages");
const Welcome = React.lazy(() => "../Pages/Welcome");
const Login = React.lazy(() => "../Pages/Login");
const Register = React.lazy(() => "../Pages/Register");

const Root = (
  <Route
    path="/"
    element={(
      <React.Suspense fallback={<>...</>}>
        <Index />
      </React.Suspense>
    )}
  >
    <Route
      element={(
        <React.Suspense fallback={<>...</>}>
          <PublicLayout />
        </React.Suspense>
      )}
    >
      <Route
        path="/login"
        element={(
          <React.Suspense fallback={<>...</>}>
            <Login />
          </React.Suspense>
        )}
      />
      <Route
        path="/register"
        element={(
          <React.Suspense fallback={<>...</>}>
            <Register />
          </React.Suspense>
        )}
      />
    </Route>

    <Route
      element={(
        <React.Suspense fallback={<>...</>}>
          <PrivateLayout />
        </React.Suspense>
      )}
    >
      <Route
        path="/welcome"
        element={(
          <React.Suspense fallback={<>...</>}>
            <Welcome />
          </React.Suspense>
        )}
      />
    </Route>
  </Route>
);

export default Root;

React.lazy

你可以将组件放置在懒加载组件的任何位置。甚至可以用一个组件包裹多个懒加载组件。
你还可以创建一个布局路由,将包裹在组件周围。
示例:
import React from "react";
import { Route } from "react-router-dom";

const PublicLayout = React.lazy(() => "../Layouts/PublicLayout");
const PrivateLayout = React.lazy(() => "../Layouts/PrivateLayout");

const Index = React.lazy(() => "../Pages");
const Welcome = React.lazy(() => "../Pages/Welcome");
const Login = React.lazy(() => "../Pages/Login");
const Register = React.lazy(() => "../Pages/Register");

const SuspenseLayout = () => (
  <React.Suspense fallback={<>...</>}>
    <Outlet />
  </React.Suspense>
);

const Root = (
  <Route element={<SuspenseLayout />}>
    <Route path="/" element={<Index />}>
      <Route element={<PublicLayout />}>
        <Route path="/login" element={<Login />} />
        <Route path="/register" element={<Register />} />
      </Route>
      <Route element={<PrivateLayout />}>
        <Route path="/welcome" element={<Welcome />} />
      </Route>
    </Route>
  </Route>
);

export default Root;

由于React.Suspense组件只需要在树中高于懒加载组件,您还可以将RouterProvider包装在Navigation中的Suspense组件中。
import React from "react";
import {
  RouterProvider,
  createBrowserRouter,
  createRoutesFromElements
} from "react-router-dom";
import Root from "./Root";

const router = createBrowserRouter(createRoutesFromElements(Root));

const Navigation = () => {
  return (
    <React.Suspense fallback={<>...</>}>
      <RouterProvider router={router} />
    </React.Suspense>
  );
};

export default Navigation;

2
我将它放在路由元素上,包裹着根组件,它的工作原理如下:

/router/index.jsx

const Root = lazy(() => import('../layout/Root'))

const Home = lazy(() => import('../pages/Home'))
const About = lazy(() => import('../pages/About'))
const Experience = lazy(() => import('../pages/Experience'))
const Projects = lazy(() => import('../pages/Projects'))
const Contact = lazy(() => import('../pages/Contact'))

export const router = createHashRouter([
  {
    path: '/',
    element: <Suspense fallback={<Loader />}><Root /></Suspense>,
    errorElement: <NotFound />,
    children: [
      {
        index: true,
        element: <Home />
      },
      {
        path: '/about',
        element: <About />
      },
      {
        path: '/experience',
        element: <Experience />
      },
      {
        path: '/projects',
        element: <Projects />
      },
      {
        path: '/contact',
        element: <Contact />
      }
    ]
  }
])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接