Building Forms in React with React Hook Form and Yup
Tags: react, typescript, form
Published: 2023-01-05 01:29:42

## Introduction to React Hook Form

React Hook Form is a powerful tool for building forms in React applications. It utilizes the power of React hooks to provide a straightforward and intuitive way to handle form state and validation. One way to add validation to a form built with React Hook Form is by using the Yup library.

## Setting up React Hook Form
To get started with React Hook Form, you will first need to install it in your project using npm: `npm install react-hook-form`. Then, you can import the `useForm` hook from the react-hook-form library and use it to create a form component. The `useForm` hook returns several functions that you can use to register input fields, handle form submission, and access errors. For example:

```tsx
import { useForm, SubmitHandler } from "react-hook-form";
interface FormInput {
	firstName: string;
	lastName: string;
}
export default function MyForm() {
	const {
		register,
		handleSubmit,
		formState: { errors },
	} = useForm<FormInput>();
	const onSubmit: SubmitHandler<FormInput> = (data) => console.log(data);
	return (
		<form onSubmit={handleSubmit(onSubmit)}>
			<input {...register("firstName")} />
			{errors.firstName && <span>This field is required</span>}
			<input {...register("lastName")} />
			{errors.lastName && <span>This field is required</span>}
			<input type='submit' />
		</form>
	);
}
```

## Adding Yup validation to React Hook Form
To add Yup validation to this form, you will need to install the Yup library: `npm install @hookform/resolvers yup`. Then, you can use the `validationSchema` option of the `useForm` hook to specify a Yup validation schema for your form. The validation schema is an object that defines the rules for each field in your form. For example:

```tsx
import { useForm, SubmitHandler } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
interface FormInput {
  firstName: string;
  lastName: string;
}
const validationSchema = yup.object().shape({
	firstName: yup.string().required("First name is required"),
	lastName: yup.string().required("Last name is required"),
});
export default function MyForm() {
	const {
		register,
		handleSubmit,
		formState: { errors },
	} = useForm <
	FormInput >
	{
		resolver: yupResolver(validationSchema),
	};
	const onSubmit: SubmitHandler<FormInput> = (data) => console.log(data);
	return (
		<form onSubmit={handleSubmit(onSubmit)} style={{ display: "flex", flexDirection: "column", gap: 4 }}>
			<div style={{ display: "flex", flexDirection: "row", gap: 3 }}>
				<label>firstName</label>
				<input {...register("firstName")} />
				{errors.firstName && <span>This field is required</span>}
			</div>
			<div style={{ display: "flex", flexDirection: "row", gap: 3 }}>
				<label>lastName</label>
				<input {...register("lastName")} />
				{errors.lastName && <span>This field is required</span>}
			</div>
			<input type='submit' />
		</form>
	);
}
```

In this example, we are using the `required` function from Yup to specify that the first name and last name fields are required. If the user tries to submit the form with these fields empty, the corresponding error messages will be displayed.

Yup also provides a range of other functions for defining validation rules. For example, you can use the `min` function to specify a minimum length for a string field, or the `max` function to specify a maximum length. You can also use the `email` function to ensure that a field contains a valid email address.

## Customizing error messages with Yup
One of the benefits of using Yup for form validation is that it allows you to customize the error messages that are displayed to the user. You can do this by specifying a string as the second argument to the required function, or by using the message function to specify a custom error message. Here is an example of how to customize the error messages for the first name and last name fields in the previous example:

```ts
const validationSchema = yup.object().shape({
	firstName: yup.string().required("First name is required").min(2, "First name must be at least 2 characters long"),
	lastName: yup.string().required("Last name is required").min(2, "Last name must be at least 2 characters long"),
});
```

In this example, we are using the `min` function to specify that the first name and last name fields must be at least 2 characters long. If the user tries to submit the form with shorter values in these fields, the corresponding error messages will be displayed.

There are many other things we can do with react-hook-form and yup such as perform asynchronous validation with Yup, manage array of fields, and watch the value of a specific form field.

I cover all this feature in my personal blog article here.
{% embed https://www.bughowi.com/blog/build-react-form-with-react-hook-form-and-yup %}

## Wrapping up
In summary, React Hook Form and Yup are great tools for building forms in React applications. They provide a simple and expressive way to handle form state and validation, and allow you to customize error messages and perform asynchronous validation. By combining these two libraries, you can build robust and user-friendly forms for your React app.