const [error, submitAction, isPending] = useActionState(
async (prevState, formData) => {
const err = await updateName(formData.get('name'));
return err ?? null;
},
null
);
<form action={submitAction}>...</form>
An Action is a function, often async, that does a piece of work such as saving data. React runs it inside a transition: a non-urgent update that React tracks from start to finish. You create one by passing a function to startTransition, or to a form's action prop. With a form, React calls it with the form's FormData.
For any Action, React gives you:
- pending state, tracked for you
- thrown errors shown in the nearest error boundary
- support for optimistic updates with
useOptimistic
Forms get one more feature. When you pass the function to <form action>, React resets the uncontrolled fields after a successful submit. Calling startTransition yourself does not reset any form.
useActionState(action, initialState) returns [state, formAction, isPending]:
- Your action receives the previous state and the form data.
- Whatever it returns becomes the new
state. This makes it a natural place for validation messages or a result. - Pass
formActionto<form action>, or to a button'sformAction. isPendingis true while the action runs.
This removes much of the manual isLoading, error and submit-handler code.
- An Action is a function, often async, that React runs inside a transition.
- Form
actionprops accept functions, which receiveFormData. - Actions give automatic pending state and error boundary support.
<form action>resets uncontrolled fields after success. A plainstartTransitioncall does not.useActionStatereturns[state, formAction, isPending].- The action receives
(prevState, formData)and returns the new state.