Why am I getting this problem?
By default, when a lazily‐loaded component isn’t yet ready, <Suspense> immediately shows its fallback UI. If that’s just a spinner or blank screen, your app “jumps” away from the current page before the new one arrives, creating a jarring flash.
Solution
You can capture and reuse the last‐rendered route component as the fallback, so it stays visible until the new one is ready. Below is a beginner‑friendly, step‑by‑step example using React‐Router v6.
1. Define your lazy routes
This code shows how to lazily load each route component on demand.
// routes.jsimport React, { lazy } from 'react';
export const routes = [
{ path: '/', element: lazy(() => import('./Home')) },
{ path: '/about', element: lazy(() => import('./About')) },
];
2. Create a wrapper that tracks the last element
Here we wrap your routes in Suspense and keep the previous view until the new one finishes loading.
//App.jsimport { useState, useEffect } from 'react';
import { BrowserRouter, useLocation, useRoutes } from 'react-router-dom';
import { routes } from './routes';
import React, { Suspense } from 'react';
function AppWrapper() {
const location = useLocation();
const element = useRoutes(routes);
const [lastRendered, setLastRendered] = useState(element);
// Whenever the route changes, remember the previous element
useEffect(() => {
setLastRendered(element);
}, [location, element]);
return (
// Use the lastRendered as the fallback until the new element loads
<Suspense fallback={lastRendered}>
{element}
</Suspense>
);
}
export default function App() {
return (
<BrowserRouter>
<AppWrapper />
</BrowserRouter>
);
}
Also Read: ReactJS Material Design
3. Breakdown of how it works
- useRoutes(routes) returns the element for the current path.
- We store that element in lastRendered every time the location or element changes.
- Wrapping in <Suspense fallback={lastRendered}> means:
- While loading the new lazy component, render lastRendered (the old page).
- Once loaded, replace it seamlessly with the new page.
Key Takeaways
- Capture the outgoing route element in state.
- Use that state as your <Suspense> fallback.
- This ensures no blank screen or spinner replaces your current page until the new one is ready.