Actions, useActionState and useOptimistic in React 19
React 19 Actions: async transitions with built-in pending state, form action functions, useActionState for results and errors, useFormStatus for nested buttons, and useOptimistic for instant UI that rolls back on failure.
Comes up in: React, Recruiter screen
Learn#
Nisha’s comment box waits a full second for the server before showing a new comment. Users click Post twice, and sometimes both get saved.
An optimistic update shows the result before the server confirms it. React 19’s useOptimistic keeps a temporary version of state that lasts only while an Action, an async transition, is running. When it ends, React shows the real state again. So a failed request rolls back by itself:
import { GlobalRegistrator } from "@happy-dom/global-registrator";
GlobalRegistrator.register(); // a DOM for Node; in a browser you already have one
const { createElement: h, useOptimistic, useState, startTransition } = await import("react");
const { createRoot } = await import("react-dom/client");
const wait = (ms) => new Promise((r) => setTimeout(r, ms));
async function saveComment(text) { // a fake server: rejects "spam"
await wait(100);
if (text === "spam") throw new Error("rejected");
return text;
}
let send;
function Comments() {
const [comments, setComments] = useState(["Nice photo!"]);
const [optimistic, addOptimistic] = useOptimistic(comments, (list, text) => [...list, `${text} (sending…)`]);
send = (text) => startTransition(async () => {
addOptimistic(text); // shows at once
try {
const saved = await saveComment(text);
startTransition(() => setComments((list) => [...list, saved]));
} catch {
// nothing to do: when the Action ends, the optimistic item disappears
}
});
return h("ul", null, optimistic.map((c) => h("li", { key: c }, c)));
}
const box = document.createElement("div");
const root = createRoot(box);
root.render(h(Comments));
await wait(20);
const show = (label) => console.log(label.padEnd(18), [...box.querySelectorAll("li")].map((li) => li.textContent).join(" | "));
send("Love it"); await wait(20); show("while sending:");
await wait(150); show("after success:");
send("spam"); await wait(20); show("while sending:");
await wait(150); show("after failure:");
root.unmount();Output (verified)
while sending: Nice photo! | Love it (sending…) after success: Nice photo! | Love it while sending: Nice photo! | Love it | spam (sending…) after failure: Nice photo! | Love it
Page
- Nice photo!
- Love it (sending…)
The user posts "Love it". Inside an Action, addOptimistic shows it at once with "(sending…)".
Read the steps as text
- The user posts "Love it". Inside an Action, addOptimistic shows it at once with "(sending…)".
- The server saves it. The real state gets the comment, and the Action ends: the optimistic copy is replaced.
- The user posts "spam". It also appears at once.
- The server rejects it. The real state never changed, so when the Action ends, the optimistic item disappears: an automatic rollback.
Predict#
Predict first
A form uses <form action={saveProfile}>. Where can a nested SubmitButton read whether the form is submitting, without props?
The useFormStatus hook reads the status of the form it is inside. So a shared button can show a spinner with no props. Call it in a component inside the form, not in the component that renders the form.
Interview angle#
Say it like this — about 30 seconds
“In React 19, an Action is an async function run in a transition. React tracks its pending state for you. A form can take a function as its action prop. The useActionState hook wraps an action. It gives back the last result and an isPending flag. The useFormStatus hook lets nested buttons read their form’s pending state. The useOptimistic hook shows a temporary value while the Action runs. If the request fails, the real state never changed. So the temporary value goes away when the Action ends.”
Follow-up What are Actions in React 19?
Follow-up How does useOptimistic work? What happens if the server request fails?
Follow-up What does useActionState return?
Practice#
Guided
Write the bookkeeping of an optimistic list: pending items, confirmations and rollbacks.
Done when
- Pending items show with “(sending…)” after the base items.
confirmmoves an item into the base list;failremoves it.- Several pending items keep their own order.
Remember#
Try to answer each card before you open it. Then add them to your reviews.
What is a React 19 Action?
An async function run in a transition, with pending state managed by React.
How long does a useOptimistic value last?
Until the Action that set it finishes.
Which hook gives a nested button its form's pending state?
useFormStatus.
What does useActionState return?
The action's last result, a wrapped action, and isPending.
Go deeper
Four layers. Stop at the one your interview needs; each ends with a quick check.
The core ideaEvery round
<form action={fn}> calls fn(formData) on submit, in a transition, and resets uncontrolled fields after success. No onSubmit, no preventDefault.Check yourself: What does a form action function receive?
A FormData object with the form's fields.
How it works underneathSenior rounds
const [state, formAction, isPending] = useActionState(action, initial): the action receives the previous state and the form data, and returns the next state, such as { error: "Email taken" } Source: React: useActionState.Check yourself: What signature does an action passed to useActionState have?
(previousState, formData) => newState (it may be async).
Edge cases and trapsWhere people slip
useFormStatus() in react-dom. It returns { pending, data, method, action } for the closest parent form.await inside an Action, wrap state updates in another startTransition, as in the example.Check yourself: Where must useFormStatus be called?
In a component rendered inside the form.
In productionStaff-level answers
useOptimistic rolls back automatically, but tell the user why it failed, with a toast or inline error Source: React: useOptimistic. Disable the submit button while pending, and send an idempotency key (WEB.15.01).
Check yourself: Why do optimistic updates still need server checks?
The server may reject the change; the UI must roll back and explain.
Finished the five steps? Mark it, and its cards join your reviews.
Last checked 2026-11-01. Spot a mistake? Use “Report an error” below — fixes are listed on the corrections page.
Interview questions this answers
- What are Actions in React 19?
- How does
useOptimisticwork? What happens if the server request fails?