Capítulo 1 de 39

Chapter 1: Get Started

Core Idea

React Hook Form is installed with a single package and wired into a form by calling useForm() and spreading register("fieldName") onto each input; validation, values, and errors all flow from that one hook call.

Key Concepts

  • register: registers an input under a field name so its value and validation participate in the form; returns { name, onChange, onBlur, ref } to spread onto the input.
  • handleSubmit: wraps your submit callback, running validation first and only invoking it with parsed data when the form is valid.
  • watch: subscribes to and returns the live value of one or more fields, triggering a re-render on change.
  • formState.errors: object holding validation errors keyed by field name, each with a type and optional message.
  • Controller: wrapper component for integrating third-party UI libraries (MUI, react-select, AntD) that don't expose a native input ref.
  • resolver: plugs in a schema library (Yup, Zod, Joi, etc.) via @hookform/resolvers so validation is defined as a schema instead of per-field rules.

Code Examples

import { useForm, SubmitHandler } from "react-hook-form"

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

export default function App() {
  const { register, handleSubmit, watch, formState: { errors } } = useForm<Inputs>()
  const onSubmit: SubmitHandler<Inputs> = (data) => 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>}
      <input type="submit" />
    </form>
  )
}
  • What it demonstrates: the minimal shape every RHF form takes — register, handleSubmit, and reading errors off formState.

Reference Tables

Validation rulePurpose
requiredfield must have a value
min / maxnumeric bounds
minLength / maxLengthstring length bounds
patternregex the value must match
validatecustom function (or map of functions) returning true/error message

Anti-patterns

  • Passing value instead of defaultValue: RHF is uncontrolled by default; setting value on a registered input fights the library and breaks the first keystroke.
  • Not integrating third-party inputs via Controller: components without a forwarded ref (MUI Select, react-select) silently fail to register without it.

Key Takeaways

  1. register + handleSubmit + formState.errors is the whole core loop for a plain HTML form.
  2. Schema validation (Yup/Zod/Joi/…) plugs in via resolver, replacing per-field rules.
  3. Controller (or useController) is the integration point for any input that can't take a raw ref.

Connects To

  • useForm: the hook that returns register, handleSubmit, watch, control, and formState.
  • Controller / useController: needed for controlled or third-party inputs.
  • register: full validation rule reference.