Form result handling
Show validation errors or a success message returned by a submitted form action.
React 19+ · Hook
useActionState updates component state from a form action's result. It returns the latest state, a form-compatible action, and a pending flag.
Call this Hook at component level with an action and initial serializable state. React passes the previous state into the action, then returns the action's latest result, a form-compatible wrapped action, and a pending flag.
const [state, formAction, isPending] = useActionState(fn, initialState, permalink?);| Name | Type | Description |
|---|---|---|
fn | function | Function called when the form is submitted or a button is pressed. It receives previous form state first, then the normal form-action arguments. |
initialState | any serializable value | Initial state value. It may be any serializable value and is used before the action runs. |
permalink | string | Optional permalink used with progressive enhancement for forms that may submit before hydration. |
An array: [state, formAction, isPending]. state is the current or latest action result; formAction is the wrapped action for a form or button; isPending indicates whether a Transition is pending.
import { useActionState } from 'react';
async function saveName(previousState: {error: string | null}, formData: FormData) {
const name = String(formData.get('name') ?? '').trim();
if (!name) return {error: 'Enter a name'};
await new Promise((resolve) => setTimeout(resolve, 300));
return {error: null};
}
export default function NameForm() {
const [state, formAction, isPending] = useActionState(saveName, {error: null});
return (
<form action={formAction}>
<input name="name" disabled={isPending} />
<button disabled={isPending}>{isPending ? 'Saving…' : 'Save'}</button>
{state.error && <p role="alert">{state.error}</p>}
</form>
);
}The action receives the previous state and submitted FormData, while the hook exposes the latest result and pending status for the form UI.
Show validation errors or a success message returned by a submitted form action.
Disable inputs and display progress while an asynchronous action is running.
Use a server function while preserving progressive enhancement and the latest response.
Invoke an action within a transition when a form element is not the direct caller.
useOptimisticstartTransitionuseFormStatusServer Functions