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.
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.
// 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>
);
}
Click the button below to mimic how Suspense waits for data. Watch the "Fallback" turn into "Data".
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.
Component Render → use() reads promise → Pending? → Suspense Fallback
Promise Resolved → UI Reveals Automatically
<Suspense> boundaryuseEffect