React-Hook-Form: How to show no error when input is blank

Viewed 4779

Once a component has been touched, and then the user clears the input, the default behaviour is that the error continues to show. How can you make it so that the error goes away when the input is cleared after touching it?

The code below is an excerpt from the docs

import React from "react";
import { useForm } from "react-hook-form";

export default function App() {
  const { register, formState: { errors }, handleSubmit } = useForm();
  
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("firstName", { required: true })} />
      {errors.firstName?.type === 'required' && "First name is required"}
      
      <input {...register("lastName", { required: true })} />
      {errors.lastName && "Last name is required"}
      
      <input type="submit" />
    </form>
  );
}

1 Answers

Your validation rules check that the fields are mandatory, so if you want the error not to appear when the fields are blank, this means that you just don't want to show the validation result at that moment.

You can choose when the validation is performed and the errors are shown with 2 options given useForm():

  • mode: this defines when the validation is performed for the first time. By default it is performed when the submit button is clicked and not before.
  • reValidateMode: this defines when the validation is performed after the first time. By default it is performed on change. This means that after the first validation, everytime a character is typed the errors will appear or disappear depending on the valid status of each field.

So you can decide to always validate on submit by giving the option {reValidateMode: "onSubmit"}, and reset the errors on change with clearErrors.

function App() {
  const {
    register,
    formState: { errors },
    handleSubmit,
    clearErrors
  } = useForm({ reValidateMode: "onSubmit" });
  const onSubmit = () => null;
  const firstName = register("firstName", { required: true });
  const lastName = register("lastName", { required: true });
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        {...firstName}
        onChange={(e) => {
          firstName.onChange(e);
          clearErrors("firstName");
        }}
      />
      {errors.firstName?.type === "required" && "First name is required"}

      <input
        {...lastName}
        onChange={(e) => {
          lastName.onChange(e);
          clearErrors("lastName");
        }}
      />
      {errors.lastName && "Last name is required"}

      <input type="submit" />
    </form>
  );
}

Here is a codesandbox for that.

You could also reset the errors only when the field is blank (instead of on every character change) by checking the value of the field before calling clearErrors, but I think it would not be very intuitive for the user to see the error disappear only when the field gets actually in an incorrect format.

Related