Suspense Basics
Suspense shows a fallback while child components wait for data or code.
Syntax
<Suspense fallback={<Spinner />}>...</Suspense><Suspense> lets you declare a fallback UI to show while its children are not ready — either their code is still loading (with lazy) or they are awaiting data (with use).
Benefits
- Declarative loading states: wrap a section, give it a fallback, done.
- You can nest boundaries so different parts of the page load independently.
Suspense replaces scattered if (loading) checks with a single boundary around the waiting content.
Example
import { Suspense, lazy } from 'react';
const Dashboard = lazy(() => import('./Dashboard.jsx'));
function App() {
return (
<Suspense fallback={<p>Loading dashboard...</p>}>
<Dashboard />
</Suspense>
);
}When to use it
- A settings page lazy-loads the AdvancedSettings panel with React.lazy so the heavy component only downloads when the user opens the settings for the first time.
- A news feed wraps each article list in Suspense so each section renders its skeleton fallback independently while data loads, rather than a single full-page spinner.
- A code-split checkout flow uses nested Suspense boundaries so the payment form shows a spinner for its own section without blocking the already-loaded shipping form.
More examples
Lazy-load a component
Dynamically imports HeavyChart so its bundle chunk loads on demand, with Suspense showing a fallback during the download.
import { lazy, Suspense } from 'react';
const HeavyChart = lazy(() => import('./HeavyChart'));
function Dashboard() {
return (
<Suspense fallback={<p>Loading chart...</p>}>
<HeavyChart />
</Suspense>
);
}Nested Suspense boundaries
Uses nested Suspense boundaries so Nav and Feed each show their own targeted skeleton while loading.
import { lazy, Suspense } from 'react';
const Nav = lazy(() => import('./Nav'));
const Feed = lazy(() => import('./Feed'));
function Layout() {
return (
<Suspense fallback={<div className="nav-skeleton" />}>
<Nav />
<Suspense fallback={<div className="feed-skeleton" />}>
<Feed />
</Suspense>
</Suspense>
);
}Suspense with use() and data
Combines Suspense with React 19's use() hook so the article skeleton appears automatically while the promise is pending.
import { use, Suspense } from 'react';
function ArticleBody({ articlePromise }) {
const article = use(articlePromise);
return <article><h1>{article.title}</h1><p>{article.body}</p></article>;
}
function ArticlePage({ id }) {
const promise = fetch(`/api/articles/${id}`).then(r => r.json());
return (
<Suspense fallback={<div className="skeleton" />}>
<ArticleBody articlePromise={promise} />
</Suspense>
);
}
Discussion