If you’ve ever worked with forms in React, you already know the pain:
- How do I know when the form is submitting?
- Should the submit button be disabled while sending data?
- How do I show success or error messages after submission?
- And what if I have multiple forms on the same page , how do I manage each one's state separately?
Before React 19, all of this required several useState
hooks, conditional logic, and a lot of boilerplate code.
But now, with the useFormStatus
hook, you can handle form states in a much cleaner and simpler way , especially when working with Server Actions in frameworks like Next.js 13+.
🚀 What Is useFormStatus
in React?
The useFormStatus
hook is a built-in React hook designed specifically for Server Actions.
It helps you track the current status of a form , whether it's being submitted, what data was sent, which method was used, and more.
Property | Description |
---|---|
pending |
Returns true when the form is currently submitting |
data |
The form data submitted by the user |
method |
The HTTP method used (POST , GET , etc.) |
action |
The action function or endpoint handling the form |
⚠ Important:
useFormStatus
only works inside a form boundary.
If you use it outside a<form>
tag,pending
will always returnfalse
.
⚙ Prerequisites
To use useFormStatus
, make sure:
- You're using React 18.3 or higher
- Your app supports Server Actions (like in Next.js 13+)
- Your form action is defined on the server using
"use server"
🧠 Example: Using useFormStatus
in React
1. Create a Server Action
// title="app/actions.ts"
"use server";
export async function createUser(formData: FormData) {
const name = formData.get("name") as string;
// Simulate network delay
await new Promise((r) => setTimeout(r, 2000));
console.log("User created:", name);
}
2. Create a Submit Button with useFormStatus
"use client";
import { useFormStatus } from "react-dom";
export function SubmitButton() {
const { pending } = useFormStatus();
return (
<button
type="submit"
disabled={pending}
className="px-4 py-2 bg-blue-600 text-white rounded"
>
{pending ? "Submitting..." : "Register"}
</button>
);
}
3. Build the Main Form
import { createUser } from "./actions";
import { SubmitButton } from "./SubmitButton";
export default function Page() {
return (
<form action={createUser} className="space-y-4">
<input
type="text"
name="name"
placeholder="Name"
className="border p-2 rounded w-full"
/>
<SubmitButton />
</form>
);
}
🔍 Advanced Tips for useFormStatus
1. Multiple Forms on One Page
Because useFormStatus
works within its own form boundary, each form manages its own state.
So if you have two forms, pressing one submit button won't affect the other , no more accidental button disabling!
2. Access More Form Data
const { pending, data, method, action } = useFormStatus();
You can use these values to:
- Log submitted form data
-
Track the submission method (
POST
,GET
, etc.) - Debug which action handled the form
3. Show Success or Error Messages
"use client";
import { useState } from "react";
import { useFormStatus } from "react-dom";
export function SubmitButtonWithMessage() {
const { pending } = useFormStatus();
const [done, setDone] = useState(false);
return (
<>
<button
type="submit"
disabled={pending}
onClick={() => setDone(false)}
className="px-4 py-2 bg-green-600 text-white rounded"
>
{pending ? "Sending..." : "Send"}
</button>
{done && <p className="text-green-600 mt-2">✅ Submission successful!</p>}
</>
);
}
You can call setDone(true)
after your server action completes (for example, after a redirect or mutation).
4. Server-Side Validation Example
Combine useFormStatus
with server-side validation for a cleaner and safer UX:
"use server";
export async function registerUser(formData: FormData) {
const email = formData.get("email") as string;
if (!email.includes("@")) {
throw new Error("Invalid email address");
}
}
This ensures validation happens securely on the server while keeping the frontend simple.
5. Improve UX During Submission
When pending
is true
:
- Disable the submit button
- Show a loading spinner
- Make form inputs read-only
This keeps users informed and prevents double submissions.
🧾 Summary
The useFormStatus
hook in React simplifies form management by letting you access the form's submission state directly within its boundary , no need for extra useState
logic.
Benefits:
- Cleaner and more maintainable code
- Independent form states
- Better UX with instant feedback
- Perfect for Next.js and React Server Actions
Top comments (0)