useActionState
is a React hook in Next.js that simplifies form-based Server Action handling with async reducer logic and built-in submission management.
Note: The second return value,
formAction
(oraction
), is essentially a wrapped Server Action. It must be used with<form action={formAction}>
or<button formAction={formAction}>
to trigger a browser POST request.
const [state, formAction, isPending] = useActionState<TState, FormData>(
actionReducer, // Server Action reducer
initialState, // Initial state value
permalink? // Optional key for state persistence
);
state
: current reducer state (initial or last returned value)formAction
: function to assign to <form action>
or <button formAction>
formData
as input.isPending
: boolean indicating submission in progress"use server";
export async function actionReducer(
prevState: TState,
formData: FormData
): Promise<TState> { /* ... */ }
prevState
: previous state provided by the hookformData
: submitted form dataformAction
to <form action={formAction}>
or <button formAction={formAction}>
formAction
can also be called manually within startTransition
.state
and toggles isPending
automatically"use client";
import { useActionState } from "react";
async function saveData(prev, formData: FormData) {
"use server";
const title = formData.get("title")?.toString() || "";
if (!title) return prev;
// database logic...
return { saved: true };
}
export function MyForm() {
const [state, action, pending] = useActionState(saveData, { saved: false });
return (
<form action={action}>
<input name="title" placeholder="Title" />
<button type="submit" disabled={pending}>Submit</button>
{state.saved && <p>Saved successfully</p>}
</form>
);
}