Suspense & Concurrent Rendering
5 questions foundWhat is Suspense in React and what basic problem does it solve?
Beginner Suspense lets a component tell React that it is not ready yet, such as while data is still loading, and React shows a fallback, like a loading spinner, until it is ready. This gives you a clean, consistent way to handle loading states without manually managing a separate loading flag everywhere.
function ProfilePage() {
return (
<Suspense fallback={<p>Loading profile</p>}>
<ProfileDetails />
</Suspense>
);
}
Real-world example A profile page shows a simple loading message while the user's details are being fetched, using Suspense to handle the waiting state cleanly instead of manually tracking a loading variable inside the component.
Common follow-ups: What kinds of things can actually trigger Suspense to show its fallback?;Can you nest multiple Suspense boundaries inside each other?
Code Splitting & Lazy Loading;Data Fetching (React Query & SWR)
How does Suspense work together with React.lazy to handle loading a component's code?
Intermediate React.lazy marks a component to be loaded only when it is actually needed, and Suspense provides the fallback content to show while that component's code is still downloading in the background. Together they let you split your app into smaller pieces without manually managing loading states for each one.
const Settings = React.lazy(() => import('./Settings'));
function App() {
return (
<Suspense fallback={<p>Loading settings</p>}>
<Settings />
</Suspense>
);
}
Real-world example An admin panel shows a brief loading message the very first time a user opens the rarely visited settings page, since that page's code is only downloaded at that exact moment, thanks to React.lazy and Suspense working together.
Common follow-ups: What happens if the lazy loaded component's code fails to download due to a network error?;Does Suspense only work with React.lazy, or can it be used for other kinds of loading too?
Code Splitting & Lazy Loading;Error Boundaries
How can Suspense be used directly for data fetching, beyond just code splitting?
Advanced Certain data fetching libraries and frameworks, including newer patterns in React itself, let a component suspend rendering while data is still being fetched, letting the same Suspense fallback mechanism handle both loading code and loading data in a unified, consistent way.
// A simplified example using a Suspense-compatible data fetching approach
function ProfileDetails() {
const user = use(fetchUserPromise); // suspends until the promise resolves
return <p>{user.name}</p>;
}
<Suspense fallback={<p>Loading</p>}>
<ProfileDetails />
</Suspense>
Real-world example A modern data heavy dashboard uses a Suspense compatible data fetching approach so that every section of the page, no matter how it loads its data, shows a consistent loading experience controlled by the same Suspense boundaries.
Common follow-ups: How is this different from the traditional useEffect plus useState pattern for fetching data?;What libraries currently support this Suspense based data fetching approach well?
Data Fetching (React Query & SWR);Server Components
How would you show multiple separate loading states for different sections of a page using several Suspense boundaries?
Intermediate Instead of wrapping an entire page in one single Suspense boundary, you can place a separate Suspense boundary around each individual section, letting each part of the page finish loading and appear independently, rather than waiting for every single piece to be ready before showing anything at all.
function Dashboard() {
return (
<div>
<Suspense fallback={<Spinner />}>
<UserStats />
</Suspense>
<Suspense fallback={<Spinner />}>
<RecentActivity />
</Suspense>
</div>
);
}
Real-world example A dashboard shows its user statistics section as soon as that specific data is ready, without waiting for a separate, slower recent activity section to also finish loading, thanks to using two independent Suspense boundaries.
Common follow-ups: What is the tradeoff between using one large Suspense boundary versus many small ones?;How would a user experience the page differently with separate boundaries compared to one shared boundary?
Performance (memo/useMemo);Design Patterns in React
What should you place inside a Suspense fallback, and what are some good practices?
Beginner A good fallback usually matches the general size and shape of the content it is replacing, such as a skeleton placeholder that resembles the layout of the actual content, rather than a small spinner that causes the page to visibly jump once the real content finally loads in.
function ProductCardFallback() {
return (
<div className="card-skeleton">
<div className="skeleton-image" />
<div className="skeleton-text" />
</div>
);
}
<Suspense fallback={<ProductCardFallback />}>
<ProductCard />
</Suspense>
Real-world example A shopping site shows a gray skeleton shape matching the size of a product card while it loads, giving a smoother visual experience than a plain spinner that would cause the page layout to jump once the real card appears.
Common follow-ups: Why does a layout shift when content finally loads create a poor user experience?;How would you build a reusable skeleton component that many different Suspense fallbacks can share?
Performance (memo/useMemo);Components & JSX