CodeForge

React 19 de Cero a Experto / Formularios y validación

React Hook Form: formularios sin dolor

Teoría22 min20 XP

Manejar un formulario grande con useState por campo es tedioso: un estado por input, un onChange por input, validación a mano, y re-renders en cada tecla. React Hook Form (RHF) lo resuelve: registras los campos con una línea, y él maneja los valores (sin controlar, así que es rápido), la validación y los errores. Es el estándar para formularios en React. Hoy dominas su API esencial: useForm, register, handleSubmit y formState.

El asistente que lleva el formulario por ti

Lo esencial: useForm, register, handleSubmit

useForm te da las herramientas; register conecta cada input; handleSubmit envuelve tu función de envío para que solo corra si la validación pasa:

rhf-basico.tsx
import { useForm } from "react-hook-form";

type Campos = { nombre: string; email: string };

function Registro() {
const {
  register,        // conecta un input al formulario
  handleSubmit,    // envuelve tu onSubmit: valida y luego llama
  formState: { errors, isSubmitting },
} = useForm<Campos>();

// solo se llama si la validación pasa; 'datos' ya está tipado
const onSubmit = async (datos: Campos) => {
  await api.registrar(datos);
};

return (
  <form onSubmit={handleSubmit(onSubmit)}>
    {/* register conecta el campo y define sus reglas */}
    <input {...register("nombre", { required: "El nombre es obligatorio" })} />
    {errors.nombre && <span>{errors.nombre.message}</span>}

    <input {...register("email", {
      required: "El email es obligatorio",
      pattern: { value: /^[^@]+@[^@]+$/, message: "Email inválido" },
    })} />
    {errors.email && <span>{errors.email.message}</span>}

    <button disabled={isSubmitting}>{isSubmitting ? "Enviando…" : "Registrarse"}</button>
  </form>
);
}

Fíjate en lo que NO hay: ni un useState por campo, ni value/onChange, ni validación manual. {...register("nombre", { required: ... })} conecta el input y declara sus reglas de una vez. handleSubmit(onSubmit) valida TODOS los campos y solo llama a tu onSubmit (con los datos ya tipados) si todo pasa; si no, llena errors. Comparado con hacerlo a mano, es una fracción del código.

register, formState y el resto

¿Qué hacen register y handleSubmit en React Hook Form?

Mini-reto

En un proyecto con RHF instalado (o razonando la API): 1) crea un formulario con useForm<{ usuario: string; edad: number }>(); 2) registra usuario con required y minLength: 3, y edad con required, min: 18 y valueAsNumber: true; 3) muestra los errores bajo cada campo y deshabilita el botón con isSubmitting. Compara mentalmente cuántas líneas te ahorras frente a hacerlo con un useState por campo y validación manual.

Qué sigue

Las reglas inline de register (required, pattern) funcionan para casos simples, pero se quedan cortas para validación seria y compartida entre cliente y servidor. Ahí entra ZOD —el mismo Zod que viste en TypeScript (SC-03)—: defines un esquema una vez y RHF lo usa para validar. La próxima lección une ambos.