React 19 made form state feel native again.
Forms are a small surface with an outsized amount of state: submission, pending work, validation, permissions, conflicts, optimistic updates, rollback, and reset behavior. Before these APIs, each component tended to rebuild some version of that machinery.
put the action at the boundary
useActionState gives the submission flow a place to live. The form invokes an action, React tracks whether it is pending, and the component receives the returned state without passing a collection of flags through the tree.
const [state, formAction, isPending] = useActionState(saveProfile, {
status: "idle",
})
return (
<form action={formAction}>
<input name="displayName" />
<button disabled={isPending}>Save</button>
{state.status === "error" ? <p>{state.message}</p> : null}
</form>
)
The important part is the shape of the contract: an input goes in, a result comes back, and the UI can render the states between those two points.
keep pending state next to the control
useFormStatus removes a common form of prop drilling. A submit button can read the surrounding form’s pending state directly, so the button can change its label or disable itself without making the parent maintain a second copy of that state.
That keeps the feedback where the user is looking: on the control that started the work.
server failure belongs in the form
Validation, permissions, conflicts, and stale data are normal server responses. Returning structured action state gives the form a way to display those failures where the user can correct them. A generic toast is sometimes useful, but it should not be the only record of why a save failed.
optimism needs a rejection path
useOptimistic helps when an interface should respond before the server finishes. It also creates a promise that the rest of the UI has to keep. If the server rejects the action, the design needs to specify what rolls back, what remains editable, and how the user learns what happened.
React 19 did not make forms automatic. It gave the asynchronous parts a shape that fits inside the component model. The result is less state-machine glue around the ordinary states users already expect to see.
Related posts

About Jeremy London
Engineering leader and builder in Denver. I write about AI platforms, agents, security, reliability, homelab infrastructure, and the parts of engineering work that have to survive production.