use + Suspense

React chapter 19 · React 19 · use() · source: react.dev/reference/react/use

The problem

Loading data by hand needs useEffect, a loading flag and a cancel flag. Switching to another person empties the card into "Loading" even though you already had something to show.

The pattern that fixes it

use(promise) reads the data right in render. If it is not ready, the nearest Suspense shows a fallback. Wrap the change in startTransition and React keeps the old card on screen, dimmed, until the new one arrives.

In plain words

Fetching data takes time. use lets a component say "I need this data" and simply wait. React shows a placeholder meanwhile, so you stop writing loading flags yourself.

A restaurant table: you order, and the waiter puts a "reserved" card down until the food comes. A transition is the better waiter who leaves your old plate in front of you until the new dish is ready.

Terms

Promise
A value that will arrive later, like a receipt for data that is still being fetched.
Suspense
A boundary component. If something inside is not ready, it shows its fallback instead.
transition
An update React treats as not urgent. It keeps the old screen while the new one prepares.

Going deeper

How does it work?

When use(promise) sees a promise that has not finished, React stops rendering that component and shows the nearest Suspense fallback. When the promise settles, React tries again and this time use returns the value. If the promise rejects, the nearest error boundary catches it. Unlike other hooks, use may be called inside if and loops.

Pitfalls and when it does nothing

The promise must be the same object on every render. Creating fetch(...) inside the component makes a new promise each time, which suspends forever. Create it in an event handler, a router loader, a Server Component, or a cache. Without startTransition, switching to data that is not ready replaces the visible content with the fallback, which is exactly the flash you see in the middle option.

When not to use it

Do not write your own promise cache for a real app. Use a data library (TanStack Query, Relay, a framework router) or Server Components, which handle caching, errors and retries. Fetching in the click handler, as this lab does, is also fine and avoids waterfalls; the React Compiler does not change any of this.

Keep learning

More courses

  • Jobs, linked to lessons — Browse jobs where every requirement links to the chapter that teaches it. See how ready you are, how long the gap takes to close, and which listings look stale.
  • Match a job post to courses — Paste a job post. Each skill is matched to a track here and put in learning order, foundations first.
  • Database in depth — How a query becomes work. Indexes, isolation, locks, and the plans that explain why a page is slow — not an ORM tour.
  • System Design — Eight interview case studies, from a flash sale and Tatkal to a live final and a chat model, plus JWT in separate chapters.
  • Microservices — Microservice patterns one diagram at a time: how to split a monolith, how services talk, and how data stays consistent without distributed transactions.
  • Kafka — A beginner-to-senior path through event logs, reliable delivery, production operations, and disaster recovery.
  • Frontend system design — How a UI is sliced when it is a product, not a page: ownership of state, cache, routes, and what happens when the network lies.
  • CSS in depth — See the box, then the page. Visual chapters from the box model through Flexbox surprises, Grid, selectors, and units, then backgrounds, shapes, and visual effects, each with a playground.
  • Accessibility — HTML labs first, then a full pass of WAI-ARIA 1.3: naming, every state, widget and structure roles, live regions, ariaNotify, and relationships.
  • Docker — What an image is, why layers cache, and how containers find each other on a network.
  • Redis — Fifteen Redis patterns, one picture each: cache, session, lock, counter, rate limiter, queue, and when Redis is the wrong tool.