useFormStatus
Reads the status of the parent form during submission. Provides pending state, form data, HTTP method, and action URL from within any component nested inside a <form>.
Signature
const { pending, data, method, action } = useFormStatus()Return Value
An object with: pending (boolean indicating submission in progress), data (FormData or null), method (HTTP method string), and action (the form action reference or URL).
Examples
import { useFormStatus } from 'react-dom';
function SubmitButton({ label = 'Submit' }: { label?: string }) {
const { pending } = useFormStatus();
return (
<button type="submit" disabled={pending}>
{pending ? (
<span>
<span className="animate-spin inline-block mr-2">⏳</span>
Submitting...
</span>
) : label}
</button>
);
}
// Usage inside a form:
// <form action={someAction}>
// <input name="email" />
// <SubmitButton label="Subscribe" />
// </form>import { useFormStatus } from 'react-dom';
function FormOverlay({ children }: { children: React.ReactNode }) {
const { pending } = useFormStatus();
return (
<div style={{ position: 'relative' }}>
{children}
{pending && (
<div style={{
position: 'absolute',
inset: 0,
background: 'rgba(0,0,0,0.5)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 8,
}}>
<span style={{ color: 'white' }}>Processing...</span>
</div>
)}
</div>
);
}import { useFormStatus } from 'react-dom';
function FormDebug() {
const { pending, data, method, action } = useFormStatus();
if (!pending) return null;
const entries = data ? Array.from(data.entries()) : [];
return (
<div style={{ background: '#1a1a2e', padding: 12, borderRadius: 8, fontSize: 12 }}>
<p>Method: {method}</p>
<p>Action: {String(action)}</p>
<p>Fields being submitted:</p>
<ul>
{entries.map(([key, val], i) => (
<li key={i}>{key}: {String(val)}</li>
))}
</ul>
</div>
);
}Common Pitfalls
Calling useFormStatus in the same component that renders the <form> — it must be in a child component nested inside the form.
Importing from 'react' instead of 'react-dom' — useFormStatus lives in the react-dom package.
Expecting useFormStatus to work outside a <form> element — it returns idle status when not inside a form.
Using it with forms that don't use the action prop — useFormStatus only tracks action-based form submissions.
Understanding useFormStatus
useFormStatus is a React DOM hook that provides submission status information for the nearest parent form element. It's designed for building reusable form UI components — like submit buttons, loading indicators, and form overlays — that automatically respond to form submission state without needing prop drilling or context.
The key architectural decision behind useFormStatus is that it reads from the parent form, not from the component that calls it. This means you must call useFormStatus in a component that is rendered inside a form element, not in the same component that renders the form. This design enables truly reusable form components that work with any form without knowing its specific action or state.
The pending field is the most commonly used property, indicating whether the form is currently being submitted. The data field provides the FormData being submitted, which is useful for showing preview information or optimistic updates. The method and action fields give you the HTTP method and target URL or action function, useful for debugging or conditional rendering.
useFormStatus pairs naturally with useActionState and useOptimistic to create polished form experiences. useActionState manages the form's state machine, useFormStatus provides awareness of submission progress to nested components, and useOptimistic enables instant feedback before the server responds. Together, these hooks provide a complete form handling system that supports progressive enhancement and server-side rendering.
Related Hooks
useActionStateManages form action state with built-in pending tracking. Combines the action function pattern with automatic state management for form submissions (React 19+).
useOptimisticShows a different state while an async action is underway, providing instant feedback by optimistically updating the UI before the server confirms the change (React 19+).
useTransitionMarks a state update as non-urgent, allowing the UI to remain responsive during the transition. Returns a pending flag and a function to wrap low-priority updates.
More Other Hooks
Explore All React Hooks
Browse our complete reference of 19 React hooks with signatures, examples, pitfalls, and in-depth explanations.