In React applications, submit buttons or loading indicators are often modular child components inside a parent <form>. Previously, passing loading states down to child components required manually passing props or Context. React 19's `useFormStatus` hook acts like a Context consumer that automatically hooks into the nearest parent <form>.

1. `useFormStatus` Syntax & Properties

import { useFormStatus } from 'react-dom';

const { pending, data, method, action } = useFormStatus();

Properties Breakdown:

  • `pending`: A boolean that is true while the parent <form> action is submitting.
  • `data`: The FormData object being submitted by the parent form (or null if not submitting).
  • `method`: The HTTP method (GET or POST).
  • `action`: Reference to the action function passed to parent <form action={...}>.
Important Rule:

`useFormStatus` MUST be called inside a component that is rendered inside a <form>. It will not read status if called inside the component that renders the <form> itself.

2. Complete Live Code Example: Reusable Submit Button Component

import React from 'react';
import { useFormStatus } from 'react-dom';

// 1. Reusable Submit Button Child Component
function SubmitButton({ label = "Submit" }) {
  // Automatically reads status of nearest parent <form>
  const { pending, data } = useFormStatus();

  return (
    <button
      type="submit"
      className="btn btn-success font-weight-bold"
      disabled={pending}
    >
      {pending ? (
        <>
          <span className="spinner-border spinner-border-sm me-2" role="status" />
          Submitting {data?.get("email")}...
        </>
      ) : (
        label
      )}
    </button>
  );
}

// 2. Parent Form Component
export default function NewsletterForm() {
  async function subscribeAction(formData) {
    await new Promise(r => setTimeout(r, 2000));
    alert(`Subscribed: ${formData.get("email")}`);
  }

  return (
    <form action={subscribeAction} className="p-4 border rounded">
      <h4>Subscribe to Tech Newsletter</h4>
      <div className="mb-3">
        <input type="email" name="email" placeholder="Enter your email" className="form-control" required />
      </div>
      {/* SubmitButton reads pending status automatically */}
      <SubmitButton label="Join Newsletter" />
    </form>
  );
}
Learn Modern React 19 Frontend Architecture

Join our live virtual classes at Telugu IT Tutorials to master React 19 hooks, Server Components, and Next.js 15. View Courses →