When we work with forms in React using React Hook Form (RHF), sometimes we get confused about isLoading and isSubmitting. These two are very useful, but they are not the same.
Today we will discuss the difference with example code so we can understand better.
π isSubmitting β When you submit the form
isSubmitting becomes true when the form is being submitted.
So, for example, when user clicks the Submit button and your form is saving data to the server, isSubmitting becomes true.
This is very useful for things like:
- Disabling the button while submitting
- Showing a spinner or loading text
Important: Your onSubmit function must return a Promise (like async function) β otherwise, isSubmitting will not work properly.
Code:
import { useForm } from "react-hook-form";
function Form() {
const {
register,
handleSubmit,
formState: { isSubmitting },
} = useForm();
const onSubmit = async (data) => {
console.log("Submitting data...", data);
await new Promise((resolve) => setTimeout(resolve, 2000)); // Fake delay
console.log("Done!");
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("name")} placeholder="Your name" />
<button type="submit" disabled={isSubmitting}>
{isSubmitting ? "Submitting..." : "Submit"}
</button>
</form>
);
}β³ isLoading β When loading default values
This one is only used when your form has async default values.
Maybe you are fetching user data from API and want to show it in the form when page loads. While it's loading, isLoading becomes true.
This is useful for:
- Showing a loading spinner or skeleton while form is not ready
- Avoiding form render until default values come
Code:
import { useForm } from "react-hook-form";
function Form() {
const {
register,
handleSubmit,
formState: { isLoading },
} = useForm({
defaultValues: async () => {
const res = await fetch("/api/user");
const data = await res.json();
return { name: data.name };
},
});
const onSubmit = async (data) => {
console.log("Saving data...", data);
};
if (isLoading) return <p>Loading form...</p>;
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("name")} />
<button type="submit">Submit</button>
</form>
);
}Comparison
| Property | Purpose | When it becomes true |
|---|---|---|
isSubmitting | When form is being submitted | During form submission |
isLoading | When loading async default values | While fetching initial data |
Final Thoughts
- Use
isSubmittingto show loading or disable submit button during submit. - Use
isLoadingwhen you are loading default values (like user profile) before form shows.
