Ad

Implement Lazy Loading In Nested Routes

I'm trying to add implement lazy loading in react app which works well in top-level routes. But I also want the <Suspense></Suspense> and provide a fallback for nested routes. According to react-router-dom, there must be only Fragment or Route as the children of Routes. Is there any way to handle this?

Here is the code:

import { lazy, Fragment, Suspense } from "react";
import { BrowserRouter, Route, Routes, Navigate } from "react-router-dom";

import Header from "./components/Header";

const Home = lazy(() => import("./components/layout/Home"));
const Destination = lazy(() => import("./components/layout/Destination"));
const Planet = lazy(() => import("./components/Planet"));
const Crew = lazy(() => import("./components/layout/Crew"));
const Biography = lazy(() => import("./components/Biography"));
const Technology = lazy(() => import("./components/layout/Technology"));
const Procedure = lazy(() => import("./components/Procedure"));

function App() {
  return (
    <BrowserRouter>
      <Header />
      <Suspense fallback={<p className='fixed left-1/2 top-1/2 -translate-x-1/2 text-2xl'>Loading ...</p>}>
        <Routes>
          <Route path="/" element={<Navigate to="home" />} />
          <Route path="home" element={<Home />} />
          <Route path="destination" element={<Destination />}>
            <Route path=":id/:planet" element={<Planet />} />
          </Route>
          <Route path="crew" element={<Crew />}>
            <Route path=":id" element={<Biography />} />
          </Route>
          <Route path="technology" element={<Technology />}>
            <Route path=":id" element={<Procedure />} />
          </Route>
        </Routes>
      </Suspense>
    </BrowserRouter>
  );
}

export default App;
Ad

Answer

You can wrap individual routed components in their own Suspense.

Example:

<BrowserRouter>
  <Header />
  <Suspense
    fallback={(
      <p className='fixed left-1/2 top-1/2 -translate-x-1/2 text-2xl'>
        Loading ...
      </p>
    )}
  >
    <Routes>
      ...
      <Route path="destination" element={<Destination />}>
        <Route
          path=":id/:planet"
          element={(
            <Suspense fallback={<>Loading Planet ...</>}>
              <Planet />
            </Suspense>
          )}
        />
      </Route>
      ...
    </Routes>
  </Suspense>
</BrowserRouter>
Ad
source: stackoverflow.com
Ad