Before react 19 developer had to choose between manual implementation or use third party library to handle the forms. Now in Modern React applications , developers want to be cleaner approach and more scalable ways to handle forms. Learning how to implement React Form using useActionState and useFormStatus hook helps simplify async forms, validations, submitted state and server actions.
In this guide, we will explore practical examples, state management techniques, how to get formData , validation strategies, error handling and best practices for implementing forms using useActionState and useFormStatus.
Table of Contents
- What is useActionState hook
- What is useFormStatus hook
- Why use them together
- Step-by-step implementation
- Validation examples
- Loading state handling
- Best practices
What is useActionState Hook?
The useActionState hook is a modern React hook used to manage form states and async operations in forms. In earlier form implementation we used to manually handle the form state and validations but with the help of this hook we can implement quickly.
It helps manage:
- Form submission state and data
- Loading status
- Error handling
- Success responses
What is useFormStatus Hook?
The useFormStatus hook is used to track the current form submission status inside nested components. so, we can use to disable the submit button or anything else we want after submit the form.
useFormStatus can help :
- Give the state of the form weather it is submitted or not
- Disable buttons when it is submitted
- Better user experience.
Why Implement React Form using useActionState and useFormStatus Hook?
Using these hooks :
- Cleaner form architecture and component
- Better async state management
- Easier loading and error handling
- Reduced too much code
- Improved scalability and optimization
- Improved user experience

Basic React Form Example
Traditional forms often require multiple states.
import { useState } from "react";
function ContactUsForm() {
const [isloading, setIsLoading] = useState(false);
async function submitHandler(e) {
e.preventDefault();
setIsLoading(true);
setTimeout(() => {
setIsLoading(false);
}, 2000);
}
return (
<form onSubmit={submitHandler}>
<input type="text" placeholder="Enter full name" />
<button type="submit">
{loading ? "Submitting..." : "Submit"}
</button>
</form>
);
}
This works, but large applications become difficult to maintain. If there are many form inputs, select or large form then need to maintain state and formdata is very hard and might be error prone.
Implement React Form with useActionState Example
Here is a cleaner modern approach.
import { useActionState } from "react";
async function ContactFormAction(prevState, formData) {
const name = formData.get("full-name");
let error = [];
if (!name) {
return {
error.push({name:"Name is required"})
};
}
return {
success: `Welcome ${fullName}`
};
}
export default function AppComponent() {
const [state, formAction, pending] = useActionState(ContactFormAction, null);
return (
<form action={formAction}>
<input
type="text"
name="full-name"
placeholder="Enter full Name"
/>
<button disabled={pending}>
{pending ? "Submitting..." : "Submited"}
</button>
{state?.error && (
{state.error.map((error)=>{
<p>error</p> })
)}
{state?.success && (
<p>{state.success}</p>
)}
</form>
);
}
This implementation automatically handles:
- Pending state
- Validation
- Success response
- Error handling
- Formdata
Implement React Form with useFormStatus Hook
The useFormStatus hook helps separate button logic into reusable components.
import { useFormStatus } from "react-dom";
function SubmitButtonAction() {
const { pending } = useFormStatus();
return (
<button disabled={pending} type=”submit”>
{pending ? "Submitting..." : "Submited"}
</button>
);
}
export default SubmitButtonAction;
Complete Example with useActionState and useFormStatus Hook
import { useActionState } from "react";
import { useFormStatus } from "react-dom";
async function submitFormAction(prevState, formData) {
const email = formData.get("email");
if (!email.includes("@")) {
return {
error: "entered Invalid Email"
};
}
return {
success: "Form Submitted"
};
}
function SubmitActionButton() {
const { pending } = useFormStatus()
return (
<button disabled={pending} type=”submit” </button> );
}
export default function AppComponent() {
const [state, formAction] = useActionState(submitFormAction, null);
return (
<form action={formAction}>
<input
type="email"
name="email"
placeholder="Enter Email"
/>
<SubmitButtonAction />
{state?.error && (
<p>{state.error}</p>
)}
{state?.success && (
<p>{state.success}</p>
)}
</form>
);
}
Hook Comparison Table
| Hook | Purpose | Best For |
| useState | Local state | Simple forms |
| useReducer | Complex state | Large applications |
| useActionState | Async action state | Modern forms |
| useFormStatus | Submission status | Loading UI handling |
Benefits of useActionState and useFormStatus
- Less code
- Better form performance
- Easy to implement.
- Cleaner code and architecture
- Easier async operation handling
- Validation effectively applied
Common Mistakes
Avoid these mistakes:
- Missing validation
- Not handling async errors
- Overusing client state
- Improper hook separation
Best Practices
- Keep actions reusable
- Use proper validation
- Keep form components small
- Keep useformstatus hook to separate component from form component
Conclusion
Learning react form with useActionState and useFormStatus hook helps developers build cleaner, scalable, and modern React applications. These hooks simplify async workflows while improving maintainability and user experience. We should use these hooks so that code will be clean and form state will be handled wisely.
FAQs
What is useActionState hook?
A React hook for handling async form actions.
What is useFormStatus hook?
A hook used to track form submission status.
Why use both hooks together?
To simplify form handling and loading state management.
Is useActionState better than useState?
For async form workflows, yes.
Final Thoughts
We should use modern hooks in modern react application to build better and optimized applications. useActionState and useFormStatus hook is very cleaner way to handle the form and form states. Although we can use manual form implementation but using formAction it is very easy to implement.