667c374e68800110f648
·3 min read

Understanding isLoading vs isSubmitting in React Hook Form

react
nextjs
react-hook-form
rhf
typescript
4d5fd787ac74e0caa4f7

Sohan R. Emon

Developer, Learner, Tech Enthusiast

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:

tsx
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:

tsx
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

PropertyPurposeWhen it becomes true
isSubmittingWhen form is being submittedDuring form submission
isLoadingWhen loading async default valuesWhile fetching initial data

Final Thoughts

  • Use isSubmitting to show loading or disable submit button during submit.
  • Use isLoading when you are loading default values (like user profile) before form shows.

Found this useful?