useFormStatus

useFormStatus reports on the most recent submission of the nearest parent <form>. It is imported from react-dom, not react, takes no arguments, and returns { pending, data, method, action }, where data is the FormData being submitted. Its one rule catches everybody once: calling it in the component that renders the <form> always returns pending: false, because from there no parent form exists. Call it from a child.

A reusable submit button that disables itselfJavaScript
import { useFormStatus } from 'react-dom';
export function SubmitButton({ children }) {
  const { pending } = useFormStatus();   // reads the nearest ANCESTOR <form>
  return <button disabled={pending}>{pending ? 'Working...' : children}</button>;
}
// Usage — SubmitButton must be *inside* the form element:
// <form action={save}><input name="q" /><SubmitButton>Save</SubmitButton></form>

That constraint is a feature. Because the button reads the status from context rather than from props, one SubmitButton serves every form in the application and no parent threads an isPending prop down. Use data for a live preview — data?.get('title') renders what is being saved while it is being saved — remembering that data is null whenever nothing is pending.