How to Build Forms Using React Hook Form and Yup

How to Build Forms Using React Hook Form and Yup

Forms are the backbone of nearly every web application, whether you’re creating a login page, a registration form, or a simple contact form. They are essential for gathering user data and ensuring a smooth interaction with your website.

As frontend developers, our mission is to collect this data efficiently, whether it’s sending information to an API, granting access to secure pages post-authentication, or displaying helpful error messages. Ideally, we want to achieve this in a way that is clean, performant, and user-friendly.

Traditional Form Handling in React

Before diving into the magic of React Hook Form and Yup, let’s briefly revisit how we typically handle forms in React without any third-party libraries. Here’s a simple example:

JSX
import React, { useState } from 'react';

const MyFormComponent = () => {
  const [state, setState] = useState({ username: '', email: '', password: '' });

  const handleChange = (event) => {
    const { name, value } = event.target;
    setState(prevState => ({ ...prevState, [name]: value }));
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    console.log(state);
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>Username</label>
        <input type="text" name="username" value={state.username} onChange={handleChange} />
      </div>
      <div>
        <label>Email</label>
        <input type="text" name="email" value={state.email} onChange={handleChange} />
      </div>
      <div>
        <label>Password</label>
        <input type="password" name="password" value={state.password} onChange={handleChange} />
      </div>
      <div>
        <button type="submit">Register</button>
      </div>
    </form>
  );
};

export default MyFormComponent;

In this example, we create a basic registration form with three fields: username, email, and password. While this works, there are some challenges.

Common Pitfalls

  1. Performance Issues: With multiple inputs, each keystroke triggers an update, causing re-renders that can slow down your application.
  2. Code Complexity: As the number of fields grows, so does the complexity of the code. Managing validations and error messages can quickly become overwhelming.

Enter React Hook Form

React Hook Form is a powerful library designed to simplify form management in React. It offers a range of benefits:

  • Lightweight: At just 8.4KB minified and gzipped, it won’t bloat your bundle.
  • Performance: By utilizing refs instead of state for input control, it minimizes unnecessary re-renders.
  • Cleaner Code: You can manage forms with fewer lines, enhancing readability and maintainability.
  • HTML-Centric: Leverage the power of native HTML for your forms.
  • Easy Validation: Integrate with libraries like Yup for schema-based validation.

Getting Started

To start using React Hook Form, install it via npm:

Bash
yarn add react-hook-form

Next, import the useForm hook in your component:

JSX
import { useForm } from 'react-hook-form';

Now, let’s rewrite our registration form using the React Hook Form:

JSX
import React from 'react';
import { useForm } from 'react-hook-form';
import { TextField, Button } from '@material-ui/core';

const MyReactHookFormComponent = () => {
  const { register, handleSubmit } = useForm();

  const submitForm = (data) => {
    console.log({ data });
  };

  return (
    <form onSubmit={handleSubmit(submitForm)}>
      <TextField inputRef={register} name="username" label="Username" />
      <TextField inputRef={register} name="email" label="Email" />
      <TextField inputRef={register} name="password" label="Password" type="password" />
      <Button type="submit">Register</Button>
    </form>
  );
};

export default MyReactHookFormComponent;

With just a few lines of code, we’ve transformed our form handling! Notice how using inputRef={register} simplifies our setup.

Validating with Yup

To add robust validation, we can integrate Yup. First, install Yup and the resolver:

Bash
yarn add yup @hookform/resolvers

Next, create a validation schema:

JSX
import * as yup from 'yup';

export const schema = yup.object().shape({
  username: yup.string().required('Username is required!'),
  email: yup.string().email('Invalid email format!').required('Email is required!'),
  password: yup.string().min(4, 'Password must be at least 4 characters long').required('Password is required!'),
});

Now, you can incorporate the schema into your form:

JSX
import { yupResolver } from '@hookform/resolvers/yup';

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

And add error messages directly in your form fields:

JSX
<TextField
  inputRef={register}
  name="username"
  label="Username"
  error={!!errors.username}
  helperText={errors.username ? errors.username.message : ''}
 />

Conclusion

React Hook Form, paired with Yup, provides a streamlined approach to building and validating forms in React. With its minimalistic design and powerful features, it enhances both user experience and developer productivity. So, whether you’re tackling a simple contact form or a complex registration process, React Hook Form and Yup have you covered!

Now, get out there and start building forms like a pro!