Free tools Windows power users keep installed
One-click scans. No signup required.
iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
useFormStatus returns pending: false when the component calling it is not nested inside the <form> it is supposed to track. The fix is to move the hook into a small child component, such as SubmitButton, and render that child inside the form. The button then reads the status of its parent form, and its disabled state and label can follow the submission.
Why pending stays false
useFormStatus does not look at whichever form is drawn nearby. It reads the status of a parent form, meaning a <form> that encloses the component calling the hook. If the calling component sits beside the form, sits above it in the tree, or is the same component that returns the form, there is no enclosing form for the hook to read, so pending never becomes true.
React’s useFormStatus reference states this case in its troubleshooting section, under the heading “status.pending is never true“: if the component that calls useFormStatus is not nested in a <form>, status.pending will always be false.
The hook is imported from react-dom and takes no parameters:
#1 Best Overall
import { useFormStatus } from 'react-dom';
The pattern that never works
The most common version of the mistake puts the hook in the same component that renders the form:
function ContactForm({ action }) {
const { pending } = useFormStatus(); // not inside a form: always false
return (
<form action={action}>
<button type="submit" disabled={pending}>Submit</button>
</form>
);
}
The button looks correct, but it never disables during submission, because the hook is called one level above the form it is meant to observe.
The SubmitButton fix
Move the hook and the button into their own component, then render that component as a child of the form:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsimport { useFormStatus } from 'react-dom';
function SubmitButton() {
const { pending } = useFormStatus();
return (
<button type="submit" disabled={pending}>
{pending ? 'Submitting…' : 'Submit'}
</button>
);
}
function ContactForm({ action }) {
return (
<form action={action}>
{/* fields */}
<SubmitButton />
</form>
);
}
SubmitButton is rendered inside the form, so the hook finds that form’s status. ContactForm only renders the form and no longer calls the hook, so nothing is read from the wrong place. React’s form documentation describes this same arrangement, a component rendered within a form that displays pending state during submission.
Rank #3
Placement compared
| Where the hook is called | Form it can observe | Result for pending |
|---|---|---|
Same component that returns the <form> |
None, because the calling component is not inside the form | Always false |
| Component rendered beside the form, outside it | None | Always false |
Child component rendered inside the <form> |
The enclosing form | Reflects that form’s submission in progress |
What useFormStatus returns
The hook returns a status object with four properties. The reference documents the following values:
| Property | Value and meaning |
|---|---|
pending |
A boolean that is true while the parent form’s submission is in progress. This is the value to use for disabled states and feedback text. |
data |
The submitted FormData while a submission is active; null otherwise. |
method |
Indicates whether the parent form uses GET or POST. |
action |
In the documented case where the parent form’s action prop is a function, this is that function. In the non-function and absent cases the reference describes, it is null. |
Diagnostic checklist
- Find the component that calls
useFormStatusin your code. - Open the rendered tree and confirm that component is a descendant of the
<form>element. A component beside the form, or one that wraps the form, will not work. - If the same component also returns the
<form>, move the hook and the button into a child component, as in the SubmitButton example above. - Confirm the child is rendered inside the form’s children, even if intermediate components sit between them.
- Test with a form whose
actionprop is a function, the arrangement used in React’s reference examples. Watch the button disable while the submission runs and re-enable afterward.
Scope of the hook
useFormStatusis part of React DOM’s browser hooks. React’s React DOM hooks overview separates these from hooks supported in non-browser environments, such as native iOS, Android, and Windows applications, so this fix applies to web React DOM apps.- The hook only reports status. It does not define the form’s action or handle the submitted data, so the server-side or client-side action function still needs to be written separately.
Sources for this article: React’s useFormStatus reference page (return values, parent-form scope, troubleshooting section), React’s <form> reference page (pending-state usage), and React’s “Built-in React DOM Hooks” overview.
Quick Recap
Best Value
Rank #4
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

