Skip to main content

React Suspense

Modern web applications often rely on code-splitting or heavy data fetching. While the data is loading, the user's screen can either appear frozen or blank.

Suspense allows you to declaratively define a fallback UI (like a loading spinner) while React waits for the internal component to be ready to render.

Usage with Lazy Loading

As your application grows, your JavaScript bundle becomes enormous, causing long initial load times. You can use React.lazy() to dynamically import components only when they are needed (e.g., when a user clicks a specific tab).

Because downloading the new component takes time, we wrap the lazy component in a <Suspense> boundary.

import { Suspense, lazy, useState } from 'react';

// The component is NOT downloaded until explicitly requested
const AdminDashboard = lazy(() => import('./AdminDashboard.jsx'));

export default function App() {
const [showAdmin, setShowAdmin] = useState(false);

return (
<div>
<button onClick={() => setShowAdmin(true)}>Load Admin Panel</button>

{showAdmin && (
<Suspense fallback={<h2>Loading dashboard code...</h2>}>
<AdminDashboard />
</Suspense>
)}
</div>
);
}

Usage with Data Fetching

In React 18 and newer frameworks like Next.js, Suspense can also automatically detect when deep components are waiting on asynchronous data APIs.

If a child component is paused mid-render waiting for an API Promise to resolve, the closest <Suspense> boundary above it will catch the pause and render the fallback UI cleanly.