Renamed in React 19
useFormState from react-dom is gone. Use useActionState from react. The new hook also returns a third value, isPending — you no longer need useFormStatus for the common case of disabling the submit button.
Shape
const [state, formAction, isPending] = useActionState(action, initialState); — render state, pass formAction to the form, disable on isPending.
Action signature
The action receives (prevState, formData) and returns the next state. Whatever it returns becomes state on the next render. This is your channel for "the action ran, here's what happened": success messages, validation errors, optimistic markers.
Model action state as a discriminated result: idle, field error, global error, or success. This lets the UI move focus, connect messages to fields, and avoid guessing from text. Keep durable records in the database and use state only to describe the latest submission. Test repeated submissions and slow responses so an older result cannot overwrite newer state. Pending UI is not decoration; it shows which submission currently owns the screen. isPending returning to false does not prove server-rendered data is current. The action must invalidate the relevant reads and the next render must receive them. Duplicating domain data into hook state creates two sources of truth.
Return success, field error, and server error in turn. Submit twice quickly and observe pending behavior. After the action resolves, compare the state message with the newly rendered server value instead of stopping at a disabled button demo.