Lesson 16 / 25

Form Actions in React 19

Server and client actions for submissions.

action, useActionState, pending states

React 19 lets you pass a function to a form's action prop; React calls it with the form data on submit and tracks pending state. Hooks such as useActionState (result and pending flag for an action) and useFormStatus (pending state inside a form) simplify submit flows, and frameworks connect actions to server functions. These APIs are newer; check the React docs and your framework's guidance before relying on them, and keep server-side validation regardless.

A form action with useActionState (sketch)

Shape of the API; not run here. Check the current React docs.

import { useActionState } from "react";

async function subscribe(prevState, formData) {
  const email = formData.get("email");
  if (!email.includes("@")) return { error: "Enter a valid email" };
  await saveSubscriber(email);             // e.g. a server function in a framework
  return { ok: true };
}

function Newsletter() {
  const [state, formAction, isPending] = useActionState(subscribe, {});
  return (
    <form action={formAction}>
      <input name="email" />
      <button disabled={isPending}>{isPending ? "Saving..." : "Subscribe"}</button>
      {state.error && <p>{state.error}</p>}
    </form>
  );
}

Show pending states

Disable the submit button and show progress while an action runs, so users do not submit twice.

Quick check: What does useActionState provide?

  • A database
  • A CSS framework
  • The latest result of an action, a wrapped action, and a pending flag
  • A router
Answer

The latest result of an action, a wrapped action, and a pending flag — Built-in submit state handling.