Suspense for Data extends React’s rendering model to handle asynchronous data fetching in a declarative way. Instead of manually managing loading flags, React can pause rendering and display fallback UI until data is ready.
SuspenseThe Suspense component wraps parts of the UI that depend on asynchronous data. When a child throws a Promise, React knows to render the fallback UI until the Promise resolves.
// Basic Suspense syntax with fallback UI
<Suspense fallback={<p>Loading...</p>}>
<MyComponent />
</Suspense>
// dataResource.js handles async data for Suspense
export function fetchUser() {
let userPromise = fetch("https://jsonplaceholder.typicode.com/users/1")
.then((res) => res.json());
return wrapPromise(userPromise);
}
function wrapPromise(promise) {
let status = "pending";
let result;
const suspender = promise.then(
(r) => { status = "success"; result = r; },
(e) => { status = "error"; result = e; }
);
return {
read() {
if (status === "pending") throw suspender;
if (status === "error") throw result;
return result;
}
};
}
// Profile component suspends until data is available
import React from "react";
import { fetchUser } from "./dataResource";
const resource = fetchUser();
export default function Profile() {
const user = resource.read();
return (
<div>
<h4>{user.name}</h4>
<p>Email: {user.email}</p>
<p>City: {user.address.city}</p>
</div>
);
}
// App component defines fallback UI
import React, { Suspense } from "react";
import Profile from "./Profile";
export default function App() {
return (
<Suspense fallback={<p>Loading user profile...</p>}>
<Profile />
</Suspense>
);
}
See how the Fallback is swapped for the Component automatically.
When resource.read() throws a Promise, React pauses rendering of that component tree. The fallback UI is displayed until the Promise resolves, then rendering continues automatically.
useTransition() for background updatesuse() API adoptionsetTimeoutGoal: Understand how Suspense simplifies async rendering and improves UX.