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.