Get started with the react-hook-form.

React hook form is a library to add validation to our forms.

zoro level security

It reduces the amount of code we need to write while removing unnecessary rerenders.

We don't have to create a state or onChange method for the form's value, it will be handled by the react-hook-form library.

By using react-hook-form we gonna avoid the calling of setState whenever input changes.

Installation

   npm install react-hook-form

Code

react-hook-form provides a useForm hook which returns methods to be used in the form.

For basic form, we can use the register and handleSumbit method.

import { useForm } from "react-hook-form"
 
export default function App() {
  const { register, handleSubmit } = useForm();
  const onSubmit = (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>
  )
}

register() method allows to register input and apply validation to it. It takes two parameters:

  1. name of the input.
  2. validation to be applied at the input.

Validation like:

  • required
  • min
  • max
  • minLength
  • maxLength
  • pattern
  • validate we can pass custom validations in the validate key.

handleSubmit() method will receive the form data if form validation is successful.

We are not using state in our form to handle the values, the benefit of this is that it will not cause rerendering of the component.

Displaying Error messages

useForm hook also provides an errors object to display errors in the form.

import { useForm } from "react-hook-form"
 
export default function App() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm()
  const onSubmit = (data) => console.log(data)
  
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        {...register("firstName", { required: true })}
      />
      {errors.firstName?.type === "required" && (
        <p role="alert">First name is required</p>
      )}
 
 
      <input
        {...register("mail", { required: "Email Address is required" })}
      />
      {errors.mail && <p role="alert">{errors.mail.message}</p>}
 
      <input type="submit" />
    </form>
  )
}

Integrating with UI libraries

In case you are using a component library like react-select, AntDesign , MUI or any other library where the component doesn't expose input's ref or say the component will not take register as prop, then we can use the Controller component, which will take care of the registration process.

import Select from "react-select"
import { useForm, Controller } from "react-hook-form"
import { Input } from "@material-ui/core"
 
const App = () => {
  const { control, handleSubmit } = useForm();
  const onSubmit = (data) => console.log(data);
 
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Controller
        name="firstName"
        control={control}
        render={({ field }) => <Input {...field} />}
      />
      <Controller
        name="select"
        control={control}
        render={({ field }) => (
          <Select
            {...field}
            options={[
              { value: "chocolate", label: "Chocolate" },
              { value: "strawberry", label: "Strawberry" },
              { value: "vanilla", label: "Vanilla" },
            ]}
          />
        )}
      />
      <input type="submit" />
    </form>
  )
}

I prefer using react-hook-form for form validation, as it avoids unnecessary codes like onChange handle or handling errors on your own.

Thanks for reading the article 🎉