Sandip Mane
by Sandip Mane
2 min read

Categories

  • React

Tags

  • react hooks

In this blog, we will create a state validation hook in react using Yup. I am also going to use ramda a functional library (if you are not using it already, do give it a try).

Yup

Yup is a JavaScript schema builder for value parsing and validation. Define a schema, transform a value to match, validate the shape of an existing value, or both. Yup schema are extremely expressive and allow modeling complex, interdependent validations, or value transformations.

Yup schema

Let’s take a simple example of a login form, check this playground for more complex use cases.

const schema = yup.object().shape({
  email: yup
    .string()
    .trim()
    .required("Email is required")
    .email("Email is invalid"),
  password: yup.string().trim().required("Password is required")
});

This is the first cut of our validation hook. It takes in the schema and the values as arguments.

We can now use it like shown below.

const {
  errors,
  handleFormSubmit
} = useValidation(schema, formValues);

Our validation hook gives us errors object and a function named handleFormSubmit. We can call handleFormSubmit on the form’s submit event or it can also be done manually if we have to.

The handleFormSubmit will take two arguments, an event and a callback which will be called upon successful validation.

This is how we can make use of it.

return (
  <form onSubmit={(e) => handleFormSubmit(e, handleSubmit)}>

Check this form live in action.


As you try filling the form, you may notice that the validations are not dynamic, we have to submit the form in order to re-validate it.

Let’s make it dynamic by adding a new function to the hook.

  const reValidate = () => {
    if (!isValidating) return;

    try {
      schema.validateSync(formValues, { abortEarly: false });
      setErrors({});
      return true;
    } catch (err) {
      if (err.name === "ValidationError") {
        const errs = mergeAll(
          err.inner.flatMap((e) => ({ [e.path]: e.errors }))
        );
        setErrors(errs);
        return false;
      }
    }
  };

We can now call this function in our component when the state changes and the validations will be running dynamically after the first form submit (Assuming we dont want to show the errors to the user as soon as they start typing).

  useEffect(() => {
    reValidate();
  }, [formValues]);

Here is our awesome dynamic form


Let’s use this same hook for more complex validations, check the following example.


Here is the full code for our useValidation hook.

Finally,

In this post, we explored how we could use react hooks and use those for our own custom validator.

And as always, thanks for reading!😃