React 19 Made Async Simpler
For years, handling asynchronous work in React meant a familiar dance: a piece of state for the data, another for loading, another for errors, and a useEffect to tie them together. React 19 introduces two features — the use() hook and Actions — that remove most of that boilerplate. Here is what they do, in plain terms.
The use() Hook
The use() hook lets a component read the value of a promise (or context) directly. Instead of fetching in an effect and juggling loading state, you pass a promise to use() and the component suspends until the data is ready, showing the nearest Suspense fallback in the meantime. The result is data-fetching code that reads top-to-bottom like synchronous code.
The key mental shift: use() works with Suspense for loading states and error boundaries for failures, so you stop manually tracking "is it loading" and "did it fail" in component state. Those concerns move to the boundaries around your component, where they belong.
Actions
Actions are React 19's answer to forms and mutations. An Action is a function — often async — that you connect to a form or trigger directly. React gives you built-in tools to track its pending state, its result, and any errors, without writing that state management yourself.
Paired with Actions are a few new hooks. One gives you the pending status of a form so you can disable a button or show a spinner. Another lets you optimistically update the UI before the server responds, then reconcile when it does — the kind of snappy experience that used to take a state library to build.
How They Fit Together
- use() — for reading async data into a component cleanly.
- Actions — for writing: form submissions and mutations with built-in pending and error handling.
- Suspense and error boundaries — the surrounding machinery that handles loading and failure states for both.
When to Reach for Each
If you are displaying data, lean on use() and Suspense. If you are submitting a form or changing data, reach for Actions and the form-status and optimistic-update hooks. You will rarely need a dedicated data-fetching or form library for standard cases anymore — React covers the common ground itself now.
A Word of Caution
New does not mean mandatory. These features shine for typical fetch-and-form work, but complex client state, real-time data, or heavy caching needs may still justify a dedicated library. Adopt the new primitives where they simplify your code, not everywhere at once.
How Dharmsy Uses React 19
We use use() and Actions to cut boilerplate on standard data and form flows, and bring in specialized libraries only where the problem genuinely calls for one. The result is less code to maintain and fewer moving parts. If you are modernizing a React codebase, we can help you adopt these cleanly.

