I Tried React 19’s useFormStatus
—Now I’ll Never Write Forms the
Old Way Again
You won’t believe how easy handling form submission just got...
Have you ever built a form in React and thought:
“Wait, why do I need six different pieces of state just to disable a submit button?”
Same. 🙋♂️
A few weeks ago, I stumbled across something new in React 19 that completely
changed how I write forms. It’s a hook called
useFormStatus
, and trust me—it’s the kind of DX improvement that makes you
actually enjoy building forms again.
In this post, I’m walking you through what it does, why it’s 🔥, and how you can start using it today. By the end, you’ll wonder how you ever survived without it.
What Is useFormStatus
?
useFormStatus
is a React 19 hook that gives you live feedback
on whether a form is currently being submitted.
That’s it. Simple, powerful, and surprisingly fun to use.
Instead of toggling a dozen state variables to handle disabled buttons,
loading spinners, and feedback messages, this hook gives you one value:
pending
.
When pending
is true
, the form is being submitted.
When it’s false
, it’s done.
That alone saved me ~40 lines of code.
Before useFormStatus
: The Pain We All Know
const [isLoading, setIsLoading] = useState(false);
// onSubmit
setIsLoading(true);
// ...async call
setIsLoading(false);
And then inside the button:
<button disabled={isLoading}>
{isLoading ? "Submitting..." : "Submit"}
</button>
Now imagine doing this across 3+ forms. It gets messy. Fast.
That’s where useFormStatus
changes the game.
The “Aha!” Moment: Real Example
I started small. Just tried it in one of my basic forms, and instantly felt the magic:
function Submit() {
const { pending } = useFormStatus();
return (
<div>
<button disabled={pending}>Submit</button>
{pending && <p>Submitting...</p>}
</div>
);
}
Then I wrapped it in a parent form:
<form action={yourActionFunction}>
<Submit />
</form>
Boom. ✨ No extra state. No callback juggling. It just worked.
Why useFormStatus
Is a Game-Changer
- ✅ Cleaner components — no more passing props back and forth.
- ✅ Instant feedback UX — loading indicators that just work.
- ✅ Way fewer bugs — no missed state updates.
- ✅ Improves accessibility — buttons disable automatically while pending.
I now use it in every form involving async logic: hitting an API, updating local state, redirecting a user—it’s just easier.
Real-World Use Case (You Can Copy)
function SubmitButton({ children }) {
const { pending } = useFormStatus();
return (
<button disabled={pending} className={`px-4 py-2 rounded ${pending ? "opacity-50" : "bg-green-600"}`}>
{pending ? "Please wait..." : children}
</button>
);
}
Then drop it into your form like:
<form action={asyncFormAction}>
<SubmitButton>Update Profile</SubmitButton>
</form>
That’s it. No extra logic. No cluttered parent components.
💡 Pro Tips to Use It Like a Senior Dev
- Only use it inside the form scope (or it won’t work).
-
Plays really well with
useActionState
for advanced handling. -
Tailwind Tip:
className={pending ? "opacity-50" : "hover:bg-blue-600"}
- Create completely reusable buttons and inputs with no props needed.
When Should You Use useFormStatus
?
Use it when:
- You’re submitting a form with async logic (like API calls)
- You want to disable buttons while submitting
- You hate repetitive
useState
code (so… always?)
Want to Go Further?
If you’re into frontend performance and next-gen UX, here’s how to level it up:
- Add a spinner (try React Spinners or Tailwind animations)
-
Combine with
useOptimistic
to pre-render UI while submitting - Add success/error messages without lifting state
Conclusion: You NEED to Try This
React 19’s useFormStatus
isn’t just a minor
improvement.
It’s a new way of thinking about form UX. If you’ve struggled with overly complex forms or just want your UI to feel snappier and cleaner, you owe it to yourself to try it.
It’s the kind of update that makes React feel ✨ modern ✨ again.
Your Turn
Go ahead, copy this working example:
👉 GitHub Source Code by github.com/azu/react-action-in-client-side-example
Then plug it into your next form. You’ll be amazed at how much cleaner and faster your UI feels.
Comments
Post a Comment