0
0
ReactHow-ToBeginner · 4 min read

How to Use Suspense with React Router for Lazy Loading

Use React's Suspense component to wrap your Routes or lazy-loaded route components in React Router. This allows you to show a fallback UI while the route components load asynchronously using React.lazy().
📐

Syntax

Wrap your Routes or individual lazy-loaded components with Suspense. Use React.lazy() to import components lazily. Provide a fallback UI to show while loading.

  • React.lazy(() => import('./MyComponent')): Lazy loads the component.
  • <Suspense fallback="<Loading />">...</Suspense>: Shows fallback UI during loading.
  • <Routes><Route path="/" element="<LazyComponent />" /></Routes>: Defines routes with lazy components.
jsx
import React, { Suspense, lazy } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';

const Home = lazy(() => import('./Home'));
const About = lazy(() => import('./About'));

function App() {
  return (
    <BrowserRouter>
      <Suspense fallback={<div>Loading...</div>}>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
        </Routes>
      </Suspense>
    </BrowserRouter>
  );
}

export default App;
Output
When navigating to '/' or '/about', the app shows 'Loading...' briefly while the component loads, then renders the Home or About page content.
💻

Example

This example shows a simple React Router setup with two lazy-loaded pages: Home and About. The Suspense component wraps the routes and displays a loading message while the pages load.

jsx
import React, { Suspense, lazy } from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';

const Home = lazy(() => new Promise(resolve => {
  setTimeout(() => resolve(import('./Home')), 1500); // Simulate network delay
}));
const About = lazy(() => new Promise(resolve => {
  setTimeout(() => resolve(import('./About')), 1500);
}));

function Loading() {
  return <div>Loading page...</div>;
}

function App() {
  return (
    <BrowserRouter>
      <nav>
        <Link to="/">Home</Link> | <Link to="/about">About</Link>
      </nav>
      <Suspense fallback={<Loading />}> 
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
        </Routes>
      </Suspense>
    </BrowserRouter>
  );
}

const container = document.getElementById('root');
const root = createRoot(container);
root.render(<App />);
Output
The app shows navigation links. Clicking Home or About shows 'Loading page...' for 1.5 seconds, then displays the page content.
⚠️

Common Pitfalls

  • Not wrapping lazy-loaded routes with Suspense causes errors because React needs a fallback UI.
  • Placing Suspense too low or too high in the tree can cause unwanted loading states or block UI updates.
  • Using synchronous imports instead of React.lazy() defeats the purpose of lazy loading.
  • Forgetting to handle loading states for nested routes can cause blank screens.
jsx
/* Wrong: No Suspense wrapper around lazy components */
import React, { lazy } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';

const Home = lazy(() => import('./Home'));

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

/* Right: Wrap Routes with Suspense */
import React, { Suspense, lazy } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';

const Home = lazy(() => import('./Home'));

function App() {
  return (
    <BrowserRouter>
      <Suspense fallback={<div>Loading...</div>}>
        <Routes>
          <Route path="/" element={<Home />} />
        </Routes>
      </Suspense>
    </BrowserRouter>
  );
}

export default App;
📊

Quick Reference

Tips for using Suspense with React Router:

  • Always wrap lazy-loaded routes or components with Suspense.
  • Use a meaningful fallback UI to improve user experience.
  • Lazy load only large or rarely used components to optimize performance.
  • Consider nested Suspense for nested routes to show partial loading states.
  • Test loading states by throttling network speed in browser DevTools.

Key Takeaways

Wrap lazy-loaded route components with React's Suspense to handle loading states.
Use React.lazy() to import route components asynchronously for better performance.
Provide a fallback UI inside Suspense to show while components load.
Avoid missing Suspense wrappers to prevent runtime errors.
Test your loading UI by simulating slow network conditions.