Form Validation with React Hook Form & Yup

As important as form validation on the front end is, It also is equally intimidating to most developers out there. But It doesn't have to be, because we now have tons of validation libraries in the react ecosystem.
There are many popular react form libraries available out there, but based on utility and simplicity, the best library I have come across is react hook form.
In the article, we are going to combine react hook form with a popular schema builder and form validation library called Yup
Installing necessary packages
// this will install react hook form and yup together
$ npm install react-hook-form yup
//this will act as a connecting agent between react form hook and yup
$ npm install @hookform/resolvers
after the installation is done, we need to import useForm hook from react-hook-form, yupResolver from yup and yup itself.
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from 'yup';
Defining a schema using Yup
Just like how a database is defined with a schema, we need to create a schema with yup.
Schema is just a pre-defined structure of the properties that you want to have in your document/table in the database.
The schema that we will be creating using yup will contain how we actually want to define the properties and whether that property is required or not, for example - we have to specify email() in the yup schema so that the input will be validated as an email before going through the request.
The way that we create schemas with yup is as follows
// this schema normally goes in a different file
const schema = yup.object().shape({
firstName: yup.string().required(),
email: yup.string().email().required(),
password: yup.string().min(8).required(),
})
Note - we need to set the name of the properties in your schema to be exactly the same as the name attributes of the input fields, this is how we identify which input are you referring to.
Once the property names are defined in the schema, we need to fill each of them with a value that will define the type of input.
We can describe the input types using yup as it contains a variety of objects that describe different inputs.
firstName: yup.string().required()
The snippet above actually says that we want to get a string type value in the firstName property which is a required field. Similarly, we have put email type on the email property which will basically check to see if the value is actually an email.
Connecting React hook form with Yup
The useForm hook that we imported from react hook form is what we are going to be making use of, so that it will take on our schema, validate the input values and display the error messages
There are three things we can get from the returned object of useForm hook, that are mainly useful
register- a function used to determine which field we want to be part of the validationhandleSubmit- a function that takes a function during onSubmit to display registered valueserrors- an object containing all of the errors
const {register, handleSubmit, formState: { errors }} = useForm({
resolver: yupResolver(schema)
});
In order to connect react hook form with yup, you need to
- Destructure the returned object from
useForm()hook and get the necessary methods from it - Inside of the
useForm()we have to pass an object that contains the resolver, this will be our Yup resolver that we imported at the top from@hookform/resolversand inside ofyupResolver()we need to pass the yup schema that we had defined earlier.
Rendering Validation Messages
Once the schema is defined and connected with react form hook, we can move ahead with registering the input fields using {...register()}
This method will be used in every input tag that you want to be part of the validation, it will register the input field and we can console log it in the submitForm function that we provided in handleSubmit
const submitForm = (data) => {
console.log(data)
}
<form onSubmit={handleSubmit(submitForm )}>
<input type="text" name='firstName' {...register("firstName")}/>
<p>{errors.firstName?.message}</p>
<input type="text" name='email' {...register("email")}/>
<p>{errors.email?.message}</p>
<input type="text" name='password' {...register("password")}/>
<p>{errors.password?.message}</p>
</form>
The last thing we need to do is to use errors to show the error messages.
errors will constantly be checking if our input fields are satisfying the schema that we defined above.
If the input values do not match the types we have defined in the schema, It will show the error message below the respective input field where we have placed it. You can even customize the error messages by defining your own error message string inside the yup validation.
That's all folks !
And that's how we can use react hook form with yup library effectively in react apps.
I will encourage you to read the documentation more in detail to understand more advanced options on your own.
Thanks for reading this quick tutorial. I hope you find it helpful! Please feel free to ask any questions in the comments below. Cheers 🍻
