November 21, 2024
Javascript programming TypeScript Web Development

Boost Your Form Handling with React Hook Form – The Ultimate Guide

Boost Your Form Handling with React Hook Form – The Ultimate Guide

React Hook Form is a tool that helps you create and validate forms easily in your React applications. It uses React hooks which make it easier to manage form state and behavior. In this article, we’ll go over what is React Hook Form, why to use React Hook Form, and show you how to use it with some simple examples.

What is React Hook Form?

React Hook Form is a tool that allows you to create forms using React hooks. Hooks makes it easier to reuse features across different components and help you avoid mistakes like too much re-rendering or memory leaks. Also, it reduces the amount of code you write but removes re-renders.

Why use React Hook Form?

React Hook Form has several advantages over other form libraries or native HTML forms. Some of these advantages are:

  • Declarative: React Hook Form enables you to write less code, but still gives you control over how your form works. Instead of worrying about small details, it means you can focus on the bigger picture – the logic and purpose of your form. You don’t need to create state variables, event handlers, or lifecycle methods for each input element. You just need to register your inputs with your form instance using the `register` method or the `Controller` component, and React Hook Form will handle the rest.
  • Performant: React Hook Form minimizes the number of re-renderings by using uncontrolled components and only updating the components that are affected by the form state changes. It also uses a smart validation system that only validates the fields that are required or have dependencies. This results in a faster and smoother user experience.
  • Flexible: React Hook Form works with any UI library or custom input component that follows the standard React pattern of accepting a `value` and an `onChange` prop. You can also customize the validation rules, error messages, default values, and other aspects of your form using various options and hooks provided by React Hook Form.
  • Easy to use: React Hook Form has a simple and intuitive API that is easy to learn and use. It also has a comprehensive documentation site with examples, tutorials, FAQs, and more. You can also find many resources online from the community, such as articles, videos, etc.

How to use React Hook Form?

Using React Hook Form is pretty straightforward.

Installing React Hook Form

npm install react-hook-form
or
yarn add react-hook-form

Simple usage: You can use it simply as in this example: 

import { useForm } from "react-hook-form";

type Inputs = {
  example: string,
  exampleRequired: string,
};

export default function App() {
  const { register, handleSubmit, formState: { errors } } = useForm<Inputs>();

  const onSubmit = (data: Inputs) => {
    // handle submit logic here
    console.log(data);
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input defaultValue="test" {...register("example")} />
      
      <input {...register("exampleRequired", { required: true })} />
      {errors.exampleRequired && <span>This field is required</span>}
      
      <button type="submit">Submit</button>
    </form>
  );
}

Registering fields: To use React Hook Form effectively, it’s important to register your component within the hook. Doing so ensures that the value of the component is accessible for both form validation and submission. It’s important to note that for the registration process, each field must have a name assigned to it which serves as its key.

Field validations: To simplify form validation, React Hook Form follows the conventional HTML standard for validation. Here are some of the available validation rules that it supports:

  • required
  • min
  • max
  • minLength
  • maxLength
  • pattern
  • validate
import { useForm, SubmitHandler } from "react-hook-form";

interface IFormInput {
  firstName: string;
  lastName: string;
  age: number;
}

export default function App() {
  const { register, handleSubmit } = useForm<IFormInput>();
  const onSubmit: SubmitHandler<IFormInput> = data => console.log(data);
   
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("firstName", { required: true, maxLength: 20 })} />
      <input {...register("lastName", { pattern: /^[A-Za-z]+$/i })} />
      <input type="number" {...register("age", { min: 18, max: 99 })} />
      <input type="submit" />
    </form>
  );
}

React Hook Form’s Custom Hooks

React Hook Form provides a set of custom hooks that you can use them to create and manage your form elements. These hooks are:

The useForm Hook

This is the main hook that is used to handle form input validation, submission, errors, and other form states.  It returns a set of functions and values to use in your form. These include things like the register function, which is used to register inputs in the form, and the handleSubmit function, which is called when the form is submitted. Here we have a simple usage of it:

import { useForm } from "react-hook-form";

function MyForm() {
  const { register, handleSubmit } = useForm();
  const onSubmit = (data) => console.log(data);
  
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input type="text" placeholder="Name" {...register("name")} />
      <input type="email" placeholder="Email" {...register("email")} />
      <button type="submit">Submit</button>
    </form>
  );
}

The useController Hook

This hook allows you to connect your form instance with controlled inputs – any custom input component that accepts a `value` and an `onChange` prop. It’s useful for creating reusable Controlled input. The below example is a simple reusable controlled input component using the useController hook.

import { TextField } from "@material-ui/core";
import { useController } from "react-hook-form";

function Input({ control, name }) {
  const {
    field,
    fieldState: { invalid, isTouched, isDirty },
    formState: { touchedFields, dirtyFields }
  } = useController({
    name,
    control,
    rules: { required: true },
  });

  return (
    <TextField 
      onChange={field.onChange}
      value={field.value}
      name={field.name}
    />
  );
}

The useFormContext Hook

This custom hook simplifies the process of accessing and using the form context in deeply nested components. As you know that passing the context around as props becomes long and difficult in nested components.

import React from "react";
import { useForm, FormProvider, useFormContext } from "react-hook-form";

export default function App() {
  const methods = useForm();
  const onSubmit = data => console.log(data);

  return (
    <FormProvider {...methods} >
      <form onSubmit={methods.handleSubmit(onSubmit)}>
        <NestedInput />
        <input type="submit" />
      </form>
    </FormProvider>
  );
}

function NestedInput() {
  const { register } = useFormContext();
  return <input {...register("test")} />;
}

The useFormState Hook

This custom hook lets you keep an eye on each part of your form and refresh only what needs updating. It only looks at the specific part of the form you tell it to, and doesn’t interfere with other parts of the form. By using this hook, you can make sure that your form only updates the parts that need it, which is really helpful for big and complicated forms as here:

import * as React from "react";
import { useForm, useFormState } from "react-hook-form";

export default function App() {
  const { register, handleSubmit, control } = useForm({
    defaultValues: {
      firstName: "Kazim"
    }
  });
  const { dirtyFields } = useFormState({
    control
  });
  const onSubmit = (data) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("firstName")} placeholder="First Name" />
      {dirtyFields.firstName && <p>Field is dirty.</p>}
      
      <input type="submit" />
    </form>
  );
}

The useFieldArray Hook

This hook allows you to manage dynamic fields in your form, like append, prepend, remove, swap, move, and insert in an array with better user experience and performance.

function FieldArray() {
  const { control, register } = useForm();
  const { fields, append, prepend, remove, swap, move, insert } = useFieldArray({
    control,
    name: "example",
  });

  return (
    {fields.map((field, index) => (
      <input
        key={field.id}
        {...register(`example.${index}.value`)} 
      />
    ))}
  );
}

The useWatch Hook

The final custom hook is the useWatch hook which works like the watch API feature, but it only re-renders at the custom hook level. This can make your application work faster and more performant.

import React from "react";
import { useForm, useWatch } from "react-hook-form";

function Child({ control }) {
  const firstName = useWatch({
    control,
    name: "firstName",
  });

  return <p>Watch: {firstName}</p>;
}

function App() {
  const { register, control } = useForm({
    firstName: "test"
  });
  
  return (
    <form>
      <input {...register("firstName")} />
      <Child control={control} />
    </form>
  );
}

To sum up, React Hook Form is a powerful tool that can greatly simplify form building in React applications. Its benefits include increased efficiency, reusability, and reduced code complexity, making it an excellent choice for developers looking to streamline their workflow. By following the basic principles of the library, utilizing custom hooks and the built-in validation methods, and leveraging the useFormContext hook for data sharing, developers can get the most out of React Hook Form and create more intuitive and user-friendly forms in their applications.

If you’re interested in learning more about programming and web development, we recommend checking out the bonus articles we’ve suggested below.

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *