The remix-run/react-router
demo shows wrapping each lazily imported component in their own React.Suspense
component:
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
You can place the Suspense
component anywhere above the lazy
component. You can even wrap multiple lazy components with a single
Suspense
component.
You could also create a layout route that wraps a React.Suspense
around an Outlet
component.
Example:
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;
Since the React.Suspense
component just needs to be higher in the tree than the lazy component, you might also wrap the RouterProvider
in Navigation
in the Suspense
component.
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;