useFormStatus — Disable While Submitting

A Hook That Knows If Its Parent Form Is Pending

useFormStatus — Disable While Submitting

Inside any `<form>`, the `useFormStatus` hook reports whether the form is currently submitting — perfect for a submit button that disables itself.

4 min read Level 2/5 #nextjs#forms#react
What you'll learn
  • Use `useFormStatus` inside a form's submit button
  • Disable the button while pending
  • Show a spinner or "Saving..." label

useActionState gives the form’s state. useFormStatus gives the form’s pending status to any descendant — no prop drilling. The classic use case is a reusable submit button.

A Reusable Submit Button

// SubmitButton.tsx
'use client'
import { useFormStatus } from 'react-dom'

export function SubmitButton({ label = 'Save' }: { label?: string }) {
  const { pending } = useFormStatus()
  return (
    <button type="submit" disabled={pending} aria-busy={pending}>
      {pending ? 'Saving...' : label}
    </button>
  )
}

Drop the component inside any <form> and it works:

import { SubmitButton } from './SubmitButton'
import { createNote } from './actions'

export default function Page() {
  return (
    <form action={createNote}>
      <input name="title" />
      <SubmitButton label="Create note" />
    </form>
  )
}

Why It Must Be a Descendant

useFormStatus reads from the closest <form> above it in the tree. If you call it in the same component that renders the <form>, you will not get the status — you have to break the button out into a child component.

What Else It Returns

The hook returns more than pending: also data (the submitted FormData), method, and action. Most of the time you only need pending.

Validation With Zod →