← Back to Chapters

Suspense for Data Fetching

⏳ Suspense for Data Fetching

? Quick Overview

React 19 introduces a more streamlined way to fetch data using Suspense combined with the new use() hook. Components can now suspend rendering until a promise resolves, letting React handle loading states declaratively.

? Key Concepts

  • Suspense pauses rendering until async data is ready
  • use() reads a promise directly inside a component
  • Fallback UI is shown automatically during loading
  • Works with concurrent rendering in React 19

? Syntax & Theory

Instead of managing useState and useEffect, you create a promise outside the component and consume it using use(). If the promise is pending, React suspends rendering and shows the nearest Suspense fallback.

? Code Example

? View Code Example
// React 19 Suspense data fetching example using use()
import React, { Suspense, use } from "react";

const fetchUsers = async () => {
const res = await fetch("https://jsonplaceholder.typicode.com/users");
if (!res.ok) throw new Error("Failed to fetch users");
return res.json();
};

const usersPromise = fetchUsers();

function UsersList() {
const users = use(usersPromise);
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}

export default function App() {
return (
<div>
<h3>Users</h3>
<Suspense fallback={<p>Loading users...</p>}>
<UsersList />
</Suspense>
</div>
);
}

? Interactive Simulation

Click the button below to mimic how Suspense waits for data. Watch the "Fallback" turn into "Data".

<Suspense Boundary />
Ready to fetch...

? Live Output / Explanation

When the component renders, use(usersPromise) checks the promise state. If it is still pending, React pauses rendering and displays Loading users.... Once resolved, the user list appears instantly without manual loading logic.

?️ Use Cases

  • Dashboards with multiple independent data sources
  • Streaming UI with progressive loading
  • Reducing loading-state boilerplate
  • Future-ready concurrent React applications

? Interactive Flow Diagram

Component Render → use() reads promise → Pending? → Suspense Fallback

Promise Resolved → UI Reveals Automatically

? Tips & Best Practices

  • Always place data-fetching components inside a <Suspense> boundary
  • Do not recreate promises on every render
  • Use nested Suspense boundaries for granular loading
  • Combine with Error Boundaries for rejected promises

? Try It Yourself

  1. Fetch posts instead of users using a public API
  2. Add multiple Suspense boundaries on the same page
  3. Trigger an error and observe behavior with an Error Boundary
  4. Compare boilerplate with traditional useEffect