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?
>Solution :
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>
);
};