Skip to content

React Hook Form

Form state built on uncontrolled inputs, so typing does not re-render the whole form.

Databases & CachingForm HandlingJavaScript

What it is

React Hook Form is a performant, flexible, and easy-to-use library for managing forms in React. It leverages uncontrolled components and React hooks to reduce re-renders and improve form performance.

React Hook Form uses the `useForm` hook to handle form state and validation. Inputs are registered via the `register` function, and submission is handled with `handleSubmit`. It supports synchronous and asynchronous validation, form resetting, error tracking, and custom input components.

Licence
MIT
Best known for
Minimal re-renders through uncontrolled inputs and refs

When to use it

The question documentation cannot answer for you — because it cannot recommend something else.

Reach for it when

  • Forms with many fields where per-keystroke re-rendering is noticeable
  • You want validation via a schema library such as Zod or Yup

Look elsewhere when

  • A two-field form where `useState` is genuinely simpler

Installation

npm install react-hook-form

Getting started

The smallest useful thing you can do with it, and what each part means.

Simple form with submit
import { useForm } from 'react-hook-form';

function MyForm() {
  const { register, handleSubmit } = useForm();
  const onSubmit = data => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('firstName')} placeholder='First Name' />
      <input {...register('lastName')} placeholder='Last Name' />
      <button type='submit'>Submit</button>
    </form>
  );
}
Defines a basic form with two fields, registering them with `useForm` and logging the submitted data.
Form with validation
const { register, handleSubmit, formState: { errors } } = useForm();
<input {...register('email', { required: true })} placeholder='Email' />
{errors.email && <span>Email is required</span>}
Adds simple required validation to a field and displays an error message if validation fails.

Advanced usage

Where the library earns its place over a simpler alternative.

Integrating with Yup validation
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from 'yup';

const schema = yup.object({ email: yup.string().email().required() });
const { register, handleSubmit, formState: { errors } } = useForm({ resolver: yupResolver(schema) });
Integrates React Hook Form with Yup schema validation for more complex rules.
Custom input component
const CustomInput = ({ register, name }) => <input {...register(name)} />;
<CustomInput register={register} name='username' />
Demonstrates how to use custom input components with React Hook Form by forwarding the `register` function.
Dynamic fields
const { fields, append, remove } = useFieldArray({ control, name: 'friends' });
fields.map((field, index) => <input {...register(`friends.${index}.name`)} />);
Manages dynamic arrays of input fields with `useFieldArray`.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

Field value not updating
Ensure the input is registered with the `register` function and the name matches.
Validation errors not showing
Check that `formState.errors` is being destructured from `useForm` and used properly in JSX.
Dynamic fields not working
Use `useFieldArray` with the `control` object and ensure proper indexing when mapping fields.

Best practices

  • Use uncontrolled components for better performance.
  • Leverage schema validation libraries like Yup or Zod for complex forms.
  • Use `useFieldArray` for dynamic fields.
  • Keep error messages user-friendly and accessible.
  • Reset forms using `reset()` when needed, especially after submission.

Alternatives

Comparable options, and the reason you would pick one over the other.

Background

Why it exists, and what it was reacting to.

React Hook Form was created by Bill Luo to simplify form management in React applications. It focuses on minimizing boilerplate, reducing unnecessary re-renders, and providing easy integration with validation libraries like Yup and Zod.