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

Example · javascript
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.

Example · jsx
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.

Example · jsx
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.

Example · jsx
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

  • Be the first to comment on this lesson.