Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning true in Yup test function is not clearing the previous error message in react-hook-form formState

Repo to duplicate the problem: https://codesandbox.io/s/yup-react-hook-form-material-checkbox-5dqbm

I am working on a form that I created with react-hook-form and yup. I have a checkbox group and I am trying to require at least one checkbox to be selected before submitting. I created a checkbox group with Material UI and handled validation with yup test function.

Here are my default values showing the structure.

 const defaultValues = {
    companyName: "",
    singleCheckbox: false,
    multiCheckbox: { option1: false, option2: false }
  };

And this is my yup validation. Basically, I am checking if one of the options of multiCheckbox is true, return true otherwise return false.

 const yupSchema = yup.object().shape({
    companyName: yup.string().required("Company name is required"),
    singleCheckbox: yup.boolean().test("singleCheckbox", "Required", (val) => {
      console.log(val, "yup singleCheckbox result");
      return val;
    }),
    multiCheckbox: yup
      .object()
      .shape({
        option1: yup.boolean(),
        option2: yup.boolean()
      })
      .test(
        "multiCheckbox",
        "At least one of the checkbox is required",
        (options) => {
          console.log(
            options.option1 || options.option2,
            "yup multiCheckbox result"
          );
          return options.option1 || options.option2;
        }
      )
  });

Problem: When I hit 'Submit' button without filling out any field, I see all the error messages that I should. And error messages are disappearing when I start filling the input form and clicking on the single checkbox but error message for multiCheckbox is not going away.

First I thought something is wrong with the test function, that's why I implemented the same logic to singleCheckbox as well. singleCheckbox is working as expected but multiCheckbox is not, even though test function of yup returns true.

What I have tried: I tried to change revalidation value of useForm to onBlur and onChange but it didn't work out for me.

Observation: Clicking on Submit button brings all the error messages. After selecting one of the options of multiCheckbox and hitting submit button again clears error message of multiCheckbox. So I am assuming there is a disconnection between yup validation and react-hook-form validation. But why same disconnection is not happening for single singleCheckbox?

like image 751
Fethi Wap Avatar asked Oct 15 '25 09:10

Fethi Wap


1 Answers

I found a workaround. Maybe someone will use it.

Create ref of clearErrors function and pass it to function returning schema so you can clear error when test is passed.

In schema test you cant use arrow function because you need this value to get field path.

const getSchema = (clearErrors) => yup.object().shape({
    companyName: yup.string().required("Company name is required"),
    singleCheckbox: yup.boolean().test("singleCheckbox", "Required", (val) => {
      console.log(val, "yup singleCheckbox result");
      return val;
    }),
    multiCheckbox: yup
      .object()
      .shape({
        option1: yup.boolean(),
        option2: yup.boolean()
      })
      .test(
        "multiCheckbox",
        "At least one of the checkbox is required",
        function (this, options) {
          console.log(
            options.option1 || options.option2,
            "yup multiCheckbox result"
          );
          if (options.option1 || options.option2) {
            clearErrors(this.path);
            return true;
          }
          return false;
        }
      )
  });


const copiedClearErrors = useRef();
  
const formMethods = useForm({
  resolver: yupResolver(getSchema(copiedClearErrors.current))
});

useEffect(() => {
  copiedClearErrors.current = formMethods.clearErrors;
}, [formMethods.clearErrors]);
like image 148
Krystian Avatar answered Oct 18 '25 00:10

Krystian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!