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.
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.