Member-only story
useActionState — a cleaner way to handle action state in React (2025)
Every interface has the moment “the user clicks → the app waits → a response arrives”.
isPending === true
— but your UI is at peace.useState
is wonderful for local values, yet once you add loading spinners, success banners and error messages, components fill up with little states. useActionState
lets me gather all those “results of one action” in a single structure and gives a built-in flag that tells me whether the action is still running. As a result:
- far less boilerplate;
- easy to disable controls while a request is pending;
- success and error handling live in one place;
- the UI stays responsive even before JavaScript is fully loaded if you rely on server components.
Anatomy of the hook
const [state, runAction, isPending] = useActionState(
async (prevState, formData) => { /* … */ },
initialState,
permalink? // optional URL for “no-JS yet” scenarios
);
- state — whatever data your action returns.
- runAction — the function you pass to
formAction
or call yourself. - isPending — automatically switches to
true
while the promise is in flight.