Skip to main content

Another Option: React Hook Form (Part 2) - Building a Complex Form #80

📖 Introduction

Following our introduction to Another Option: React Hook Form (Part 1), this article takes a deeper dive into its capabilities. We will learn how to build a complex form with React Hook Form, integrate with the Yup library for powerful and flexible validation, and use the @hookform/resolvers package to connect them.


📚 Prerequisites

Before we begin, please ensure you have a solid grasp of the following concepts:

  • All concepts from Part 1 of this series.
  • npm or yarn for installing packages.

🎯 Article Outline: What You'll Master

In this article, you will learn:

  • Schema Validation with Yup: How to integrate the Yup library to create powerful and readable validation schemas.
  • The @hookform/resolvers Package: How to use this package to connect React Hook Form with Yup.
  • Building a Complex Form: We will build a complete registration form with multiple fields and complex validation rules.

🧠 Section 1: The Core Concepts of Schema Validation with Yup

While React Hook Form has its own built-in validation, it also integrates seamlessly with schema validation libraries like Yup. This allows you to define your validation rules in a separate object, keeping your component code clean and focused.

The @hookform/resolvers package is a small utility that allows you to use any schema validation library (like Yup, Zod, Joi, etc.) with React Hook Form.


💻 Section 2: Deep Dive - Implementation and Walkthrough

Let's build a registration form with React Hook Form and Yup.

2.1 - Installation

First, you need to install React Hook Form, Yup, and the resolver:

npm install react-hook-form yup @hookform/resolvers

2.2 - Creating the Validation Schema with Yup

Let's create a validationSchema.js file to define our validation rules.

// validationSchema.js
import * as yup from 'yup';

export const validationSchema = yup.object({
firstName: yup.string()
.max(15, 'Must be 15 characters or less')
.required('Required'),
lastName: yup.string()
.max(20, 'Must be 20 characters or less')
.required('Required'),
email: yup.string().email('Invalid email address').required('Required'),
password: yup.string()
.min(8, 'Password must be at least 8 characters')
.required('Required'),
confirmPassword: yup.string()
.oneOf([yup.ref('password'), null], 'Passwords must match')
.required('Required'),
}).required();

2.3 - Building the Form

Now, let's build our registration form.

// code-block-1.jsx
import React from 'react';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { validationSchema } from './validationSchema';

function RegistrationForm() {
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: yupResolver(validationSchema),
});

const onSubmit = (data) => {
alert(JSON.stringify(data));
};

return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label htmlFor="firstName">First Name</label>
<input id="firstName" {...register('firstName')} />
<p>{errors.firstName?.message}</p>
</div>
<div>
<label htmlFor="lastName">Last Name</label>
<input id="lastName" {...register('lastName')} />
<p>{errors.lastName?.message}</p>
</div>
<div>
<label htmlFor="email">Email Address</label>
<input id="email" {...register('email')} />
<p>{errors.email?.message}</p>
</div>
<div>
<label htmlFor="password">Password</label>
<input id="password" type="password" {...register('password')} />
<p>{errors.password?.message}</p>
</div>
<div>
<label htmlFor="confirmPassword">Confirm Password</label>
<input id="confirmPassword" type="password" {...register('confirmPassword')} />
<p>{errors.confirmPassword?.message}</p>
</div>
<button type="submit">Submit</button>
</form>
);
}

export default RegistrationForm;

Step-by-Step Code Breakdown:

  1. import { yupResolver } from '@hookform/resolvers/yup';: We import the yupResolver.
  2. resolver: yupResolver(validationSchema): We pass the yupResolver to the useForm hook, with our validation schema as an argument.
  3. {...register('firstName')}: The register function connects the input to React Hook Form.
  4. <p>{errors.firstName?.message}</p>: We display the error message for the corresponding field.

💡 Conclusion & Key Takeaways

In this article, we've learned how to use React Hook Form with the Yup library to build complex forms with powerful validation. This approach gives you the performance benefits of React Hook Form and the declarative power of Yup.

Let's summarize the key takeaways:

  • React Hook Form can be integrated with schema validation libraries like Yup.
  • The @hookform/resolvers package is used to connect React Hook Form with Yup.
  • This combination allows you to build complex, performant, and maintainable forms.

Challenge Yourself: To solidify your understanding, try to add a checkbox to the form for accepting terms and conditions, with validation to ensure it is checked.


➡️ Next Steps

This concludes our series on building forms in React. You now have a solid understanding of controlled components, uncontrolled components, and two of the most popular form libraries in the React ecosystem. In the next series, we will explore the power of Custom Hooks.

Thank you for your dedication. Stay curious, and happy coding!


glossary

  • Yup: A JavaScript schema builder for value parsing and validation.
  • @hookform/resolvers: A package that provides resolvers for using schema validation libraries with React Hook Form.
  • Schema: A representation of a plan or theory in the form of an outline or model.

Further Reading