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

Los formularios son una parte esencial de cualquier aplicación web. En React, la solución más sencilla suele ser manejar cada campo con useState. Sin embargo, a medida que el número de inputs crece, esa estrategia se vuelve engorrosa y propensa a errores. En este artículo vamos a ver cómo react-hook-form simplifica la vida, ofreciendo mejor rendimiento y una API declarativa.
¿Por qué useState se queda corto?
Imagina un formulario de registro con diez campos. Con useState tendrías que crear un estado para cada uno, actualizarlo en cada onChange y, al final, recopilar todos los valores para enviarlos. El código termina siendo algo así:
import React, { useState } from 'react';
function Registro() {
const [nombre, setNombre] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
// ...más campos
const handleSubmit = e => {
e.preventDefault();
const datos = { nombre, email, password / ... / };
console.log(datos);
};
return (
<form onSubmit={handleSubmit}>
<input value={nombre} onChange={e => setNombre(e.target.value)} />
<input value={email} onChange={e => setEmail(e.target.value)} />
<input type="password" value={password} onChange={e => setPassword(e.target.value)} />
{/ ...más inputs /}
<button type="submit">Enviar</button>
</form>
);
}
Este enfoque tiene varios problemas:
- Repetición de código: cada campo necesita su propio estado y manejador.
- Escalabilidad: añadir o eliminar campos implica modificar varios lugares.
- Validación: gestionar errores de forma manual puede resultar verboso.
Enter react-hook-form
Esta librería está diseñada para trabajar con formularios sin necesidad de crear estados para cada campo. Utiliza refs y un registro interno que mantiene los valores y errores, lo que reduce el número de renders y mejora el rendimiento.
Instalación
Solo necesitas ejecutar:
npm install react-hook-form
o, si usas Yarn:
yarn add react-hook-form
Uso básico
Veamos cómo migrar el ejemplo anterior a react-hook-form:
import React from 'react';
import { useForm } from 'react-hook-form';
function Registro() {
const { register, handleSubmit, formState: { errors } } = useForm();
const onSubmit = data => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('nombre', { required: true })} />
{errors.nombre && <span>Este campo es obligatorio</span>}
<input {...register('email', { required: true, pattern: /^[^@\s]+@[^@\s]+\.[^@\s]+$/ })} />
{errors.email && <span>Introduce un email válido</span>}
<input type="password" {...register('password', { required: true, minLength: 6 })} />
{errors.password && <span>La contraseña debe tener al menos 6 caracteres</span>}
<button type="submit">Enviar</button>
</form>
);
}
Observa las diferencias:
- No hay
useStatepara cada campo. - Los
registergestionan tanto el valor como la validación. - Los errores están disponibles en
formState.errors.
Validaciones más avanzadas
Con react-hook-form puedes añadir reglas complejas sin escribir lógica extra. Por ejemplo, validar que dos contraseñas coincidan:
const { register, handleSubmit, watch, formState: { errors } } = useForm();
const password = watch('password');
<input type="password" {...register('confirmPassword', {
validate: value => value === password || 'Las contraseñas no coinciden'
})} />
{errors.confirmPassword && <span>{errors.confirmPassword.message}</span>}
Rendimiento
Al no actualizar el estado del componente en cada cambio de input, react-hook-form evita renders innecesarios. En pruebas simples, un formulario con 20 campos renderiza menos de la mitad de veces que una solución basada en useState. Esto se traduce en una UI más fluida, sobre todo en dispositivos móviles.
Conclusiones
Si estás empezando con formularios en React, useState sirve para prototipos rápidos, pero pronto notarás sus limitaciones. react-hook-form ofrece una API limpia, validaciones declarativas y un gran salto de rendimiento. Integra la librería en tu próximo proyecto y verás cuánto código puedes eliminar mientras mantienes la robustez que necesitas.