Formularios en React: de useState a react-hook-form

Coding on a laptop outdoors, showcasing a rooftop urban lifestyle in Surat, India.
Foto de Meet Patel en Pexels

Los formularios son una pieza clave en cualquier aplicación web. En React, la forma más sencilla de empezar es usar useState para ir guardando los valores de cada input. Es una solución directa, pero a medida que el número de campos crece o aparecen validaciones complejas, el código se vuelve verboso y propenso a errores. En este artículo vamos a repasar el enfoque clásico con useState y, a continuación, veremos por qué react-hook-form es una alternativa mucho más ligera y escalable.

Gestión de formularios con useState

Con useState cada campo del formulario necesita su propio estado o, en caso de formularios pequeños, podemos agruparlos en un único objeto. Cada onChange actualiza el estado y, al enviar, leemos los valores para procesarlos.

import React, { useState } from 'react';

function FormularioSimple() {
  const [form, setForm] = useState({ nombre: '', email: '' });

  const handleChange = e => {
    const { name, value } = e.target;
    setForm(prev => ({ ...prev, [name]: value }));
  };

  const handleSubmit = e => {
    e.preventDefault();
    console.log(form);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input name="nombre" value={form.nombre} onChange={handleChange} placeholder="Nombre" />
      <input type="email" name="email" value={form.email} onChange={handleChange} placeholder="Email" />
      <button type="submit">Enviar</button>
    </form>
  );
}

Este patrón funciona, pero ya vemos algunos puntos débiles: cada cambio dispara una re‑render del componente, la lógica de validación se mezcla con la de actualización y, si añadimos más campos, el código crece linealmente.

Limitaciones del enfoque tradicional

Al usar useState para cada input, el rendimiento puede verse afectado porque React vuelve a renderizar el componente completo con cada tecla pulsada. Además, gestionar errores y mensajes de validación implica crear más estados o estructuras auxiliares, lo que complica el mantenimiento. Cuando el formulario incluye arrays dinámicos (por ejemplo, una lista de teléfonos) o validaciones dependientes, la lógica se vuelve aún más engorrosa.

¿Qué aporta react-hook-form?

react-hook-form está diseñada para minimizar re‑renders y centralizar la gestión de valores, errores y estados de validación. Utiliza refs bajo el capó, por lo que los campos no necesitan estar ligados a un state de React. El API principal es useForm, que devuelve register, handleSubmit y formState. Con register vinculamos un input al formulario y declaramos reglas de validación de forma declarativa.

Ejemplo práctico con react-hook-form

A continuación, un formulario sencillo que recoge nombre y email, valida que ambos sean obligatorios y que el email tenga formato correcto.

import React from 'react';
import { useForm } from 'react-hook-form';

function MiFormulario() {
  const { register, handleSubmit, formState: { errors } } = useForm();
  const onSubmit = data => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('nombre', { required: true })} placeholder='Nombre' />
      {errors.nombre && <span>Este campo es obligatorio</span>}

      <input type='email' {...register('email', {
        required: true,
        pattern: /^[^@\s]+@[^@\s]+\.[^@\s]+$/
      })} placeholder='Email' />
      {errors.email && <span>Email no válido</span>}

      <button type='submit'>Enviar</button>
    </form>
  );
}

Observa cómo no necesitamos crear estados ni manejadores de onChange para cada campo. La librería se encarga de registrar los valores y de actualizar errors automáticamente. Además, el número de re‑renders es mucho menor: sólo se vuelve a renderizar el componente cuando ocurre una validación o al enviar el formulario.

Comparativa y buenas prácticas

  • Simplicidad: con react-hook-form el código del formulario es más conciso y legible.
  • Rendimiento: al evitar setState en cada pulsación, la UI responde más rápido, especialmente en formularios extensos.
  • Escalabilidad: añadir nuevos campos o validaciones es cuestión de ampliar el objeto pasado a register, sin tocar la lógica de envío.
  • Integración: la librería funciona bien con componentes UI de terceros (Material‑UI, Ant Design, etc.) gracias a su API basada en refs.

Si ya usas useState en formularios pequeños, no es necesario migrar de inmediato. Sin embargo, cuando el número de campos supera los cinco o la lógica de validación se vuelve compleja, react-hook-form te ahorrará tiempo y código.

Conclusión

Pasar de useState a react-hook-form es un paso natural para cualquier desarrollador frontend que quiera crear formularios robustos y de alto rendimiento en React. La librería reduce la carga mental al abstraer la gestión de estado y validación, y permite centrarse en la lógica de negocio. Prueba el ejemplo, experimenta con reglas personalizadas y verás cómo tu código gana en claridad y velocidad.