Handling Forms via Form ActionsEntry 6 of 10

useFormStatus: Pending State in Child Components

useFormStatus() (from react-dom) returns the submission status of the parent <form>: { pending, data, method, action }.

Notes

  • The component calling it must be rendered inside the <form>. It reads the nearest ancestor form, not a form rendered in the same component.
  • Its main use: a reusable <Submit> button that disables itself, with no props passed down.
  • data is the FormData being submitted (null when idle), useful for showing what's being sent.
  • It works with any function action, with or without useActionState.
AspectuseActionStateuseFormStatus
Packagereactreact-dom
Called inThe component that renders the formA component inside the form
Givesstate, formAction, isPendingpending, data, method, action
Use forResults and errorsReusable buttons and spinners

What / Why / When

What

Form status available to any descendant.

Why

No prop drilling of isPending into buttons.

When

Shared submit buttons or loading indicators used across forms.

Use case

A <Submit> button used in the opinion form.

Code compare

React
// Submit.tsximport { useFormStatus } from "react-dom";​export default function Submit() {  const { pending } = useFormStatus();​  return (    <p className="actions">      <button type="submit" disabled={pending}>        {pending ? "Submitting..." : "Submit"}      </button>    </p>  );}

There's no context-based form status. The usual pattern passes the pending signal down as an input:

Angular
// submit-button.component.ts@Component({  selector: "app-submit-button",  template: `    <p class="actions">      <button type="submit" [disabled]="pending()">        {{ pending() ? "Submitting..." : "Submit" }}      </button>    </p>  `,})export class SubmitButtonComponent {  pending = input(false);}

To avoid passing it through several levels, provide a small state service on the form component (providers: [FormStatusService]) and inject() it in the button. Children get the same instance, which mimics useFormStatus.

Differences and gotchas

  • Calling useFormStatus() in the same component that renders the <form> always returns pending: false. Move it into a child.
  • Import from react-dom, not react.

Quick reference

React 19Angular
useFormStatus() in a childpending input, or a component-level service
pendingisPending() signal
dataform.getRawValue()