The use() Hook
use() reads the value of a resource — like a Promise or a Context — and can be called conditionally, unlike other hooks. When passed a Promise, it suspends the component until the Promise resolves, integrating naturally with Suspense.
Reading a Promise with use()
import { use, Suspense } from "react";
function UserProfile({ userPromise }) {
const user = use(userPromise); // suspends until resolved
return <h1>{user.name}</h1>;
}
function App({ userPromise }) {
return (
<Suspense fallback={<p>Loading...</p>}>
<UserProfile userPromise={userPromise} />
</Suspense>
);
}Actions
An Action is an async function passed to a form’s action prop (or used with useTransition), which React handles automatically — managing pending state, errors, and optimistic updates without manually wiring up useState for each of those concerns.
A Form Using an Action
function UpdateNameForm() {
async function updateName(formData) {
const name = formData.get("name");
await saveName(name);
}
return (
<form action={updateName}>
<input type="text" name="name" />
<button type="submit">Save</button>
</form>
);
}useActionState
useActionState wraps an Action and gives you back its current state (like a success message or validation error) along with a pending flag, without manually tracking either with separate useState calls.
useActionState Example
import { useActionState } from "react";
function ChangeNameForm() {
const [error, submitAction, isPending] = useActionState(
async (previousState, formData) => {
const name = formData.get("name");
if (!name) return "Name is required";
await saveName(name);
return null;
},
null
);
return (
<form action={submitAction}>
<input type="text" name="name" />
<button disabled={isPending}>Save</button>
{error && <p>{error}</p>}
</form>
);
}useOptimistic
useOptimistic lets the UI show an expected result immediately, before an async Action actually finishes — automatically reverting if the action fails, giving a snappier feel for actions like liking a post or sending a message.
Optimistic UI Update
import { useOptimistic } from "react";
function LikeButton({ likes, onLike }) {
const [optimisticLikes, addOptimisticLike] = useOptimistic(
likes,
(state) => state + 1
);
async function handleLike() {
addOptimisticLike();
await onLike(); // if this fails, optimisticLikes reverts automatically
}
return <button onClick={handleLike}>❤️ {optimisticLikes}</button>;
}The ref Prop No Longer Needs forwardRef
As of React 19, function components can accept ref directly as a regular prop, removing the need for forwardRef() in most cases where a component just needs to expose an underlying DOM node.
Best Practice
Reach for Actions and useActionState for form submissions instead of manually wiring useState for pending/error/success — they cover the most common form-handling boilerplate with far less code.