I want apply lazy loading to specific routes. I want something like this:
import { lazy, Suspense } from "react";
import { Route, Routes } from "react-router-dom";
import NotLazyComponent from "./NotLazyComponent";
const LazyOne = lazy(() => import("./LazyOne"));
const LazyTwo = lazy(() => import("./LazyTwo"));
const App = () => {
return (
<Routes>
<Route path="/not-lazy" element={<NotLazyComponent />} />
<Suspense fallback={<div>Loading...</div>}>
<Route path="/lazy-one" element={<LazyOne />} />
<Route path="/lazy-two" element={<LazyTwo />} />
</Suspense>
</Routes>
);
};
export default App;
but this won't work. What is the correct way to do that?
Only the Route
and React.Fragment
components are valid children of the Routes
component. Suspense
needs to be rendered elsewhere.
You could wrap individual routes in the Suspense
component:
const App = () => {
return (
<Routes>
<Route path="/not-lazy" element={<NotLazyComponent />} />
<Route
path="/lazy-one"
element={(
<Suspense fallback={<div>Loading...</div>}>
<LazyOne />
</Suspense>
)}
/>
<Route
path="/lazy-two"
element={(
<Suspense fallback={<div>Loading...</div>}>
<LazyTwo />
</Suspense>
)}
/>
</Routes>
);
};
Create a layout route that wraps the lazily loaded nested route components:
import { Routes, Route, Outlet } from 'react-router-dom';
const SuspenseLayout = () => (
<Suspense fallback={<div>Loading...</div>}>
<Outlet />
</Suspense>
);
const App = () => {
return (
<Routes>
<Route path="/not-lazy" element={<NotLazyComponent />} />
<Route element={<SuspenseLayout />}>
<Route path="/lazy-one" element={<LazyOne />} />
<Route path="/lazy-two" element={<LazyTwo />} />
</Route>
</Routes>
);
};
Or lift the Suspense
component higher in the ReactTree outside the Routes
component:
const App = () => {
return (
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/not-lazy" element={<NotLazyComponent />} />
<Route path="/lazy-one" element={<LazyOne />} />
<Route path="/lazy-two" element={<LazyTwo />} />
</Routes>
</Suspense>
);
};