Los formularios son una parte fundamental de cualquier aplicación web. Un registro, inicio de sesión, búsqueda, checkout o formulario de contacto necesita capturar información y, sobre todo, validarla correctamente antes de enviarla.
En React podemos manejar formularios utilizando useState, eventos y validaciones personalizadas. Sin embargo, en aplicaciones reales conviene aplicar una estructura más organizada para evitar código difícil de mantener.
1. Controlar los campos con React
Una forma sencilla de comenzar es utilizando useState para almacenar los valores:
import { useState } from "react";
function Registro() {
const [formulario, setFormulario] = useState({
nombre: "",
email: "",
password: ""
});
const handleChange = (e) => {
setFormulario({
...formulario,
[e.target.name]: e.target.value
});
};
return (
<form>
<input
name="nombre"
value={formulario.nombre}
onChange={handleChange}
placeholder="Nombre"
/>
<input
name="email"
type="email"
value={formulario.email}
onChange={handleChange}
placeholder="Correo"
/>
<input
name="password"
type="password"
value={formulario.password}
onChange={handleChange}
placeholder="Contraseña"
/>
</form>
);
}
La propiedad name permite identificar qué campo cambió y actualizar solamente ese valor.
2. Crear validaciones reales
No debemos confiar únicamente en required o type="email". Las aplicaciones reales necesitan reglas adicionales.
Por ejemplo:
const validar = () => {
const errores = {};
if (!formulario.nombre.trim()) {
errores.nombre = "El nombre es obligatorio";
}
if (!formulario.email.includes("@")) {
errores.email = "Introduce un correo válido";
}
if (formulario.password.length < 8) {
errores.password =
"La contraseña debe tener mínimo 8 caracteres";
}
return errores;
};
Podemos guardar estos errores en otro estado:
const [errores, setErrores] = useState({});
Y utilizarlos para mostrar mensajes al usuario:
{errores.email && (
<span>{errores.email}</span>
)}
Esto proporciona una experiencia mucho mejor que simplemente mostrar un mensaje genérico después de enviar el formulario.
3. Validar antes de enviar
El evento onSubmit es el lugar adecuado para ejecutar la validación:
const handleSubmit = (e) => {
e.preventDefault();
const erroresValidacion = validar();
setErrores(erroresValidacion);
if (Object.keys(erroresValidacion).length > 0) {
return;
}
console.log("Formulario válido", formulario);
};
Primero evitamos que el navegador recargue la página, después ejecutamos las validaciones y solamente continuamos si no existen errores.
4. Validación en tiempo real
Una aplicación profesional también puede validar mientras el usuario escribe o cuando abandona un campo.
Por ejemplo, podemos utilizar onBlur para comprobar un campo cuando pierde el foco:
<input
name="email"
value={formulario.email}
onChange={handleChange}
onBlur={() => {
// Validar email
}}
/>
Esto permite detectar errores rápidamente sin esperar a que el usuario pulse el botón de enviar.
5. ¿Y cuando el formulario crece?
Cuando tenemos formularios pequeños, useState puede ser suficiente. Pero si existen muchos campos, reglas complejas, validaciones condicionales y mensajes personalizados, mantener todo manualmente puede generar demasiado código.
En esos casos existen herramientas como React Hook Form y Zod, que permiten separar la lógica del formulario de las reglas de validación.
Una combinación habitual es:
React → React Hook Form → Zod → API
React Hook Form administra los campos y el estado del formulario, mientras Zod permite definir un esquema de validación reutilizable.
6. Nunca olvides la validación del backend
Existe un error muy importante: pensar que validar en React es suficiente.
La validación del frontend mejora la experiencia del usuario, pero no proporciona seguridad. Un usuario puede modificar las peticiones desde el navegador y enviar información directamente a nuestra API.
Por eso debemos validar en ambos lados:
Frontend: experiencia de usuario y errores inmediatos.
Backend: seguridad, integridad y reglas de negocio.
Por ejemplo, aunque React compruebe que un correo tiene un formato correcto, el servidor debe volver a comprobarlo antes de guardar los datos.
Conclusión
Manejar formularios profesionalmente en React no consiste solamente en leer valores de inputs. Una implementación sólida debe controlar el estado, validar los datos, mostrar errores claros, evitar envíos incorrectos y comprobar nuevamente la información en el backend.
Para proyectos pequeños, useState puede ser suficiente. Para aplicaciones grandes, herramientas como React Hook Form y Zod ayudan a crear formularios más limpios, escalables y fáciles de mantener.
La clave está en diseñar los formularios pensando no solo en cómo capturar datos, sino también en cómo garantizar que esos datos sean válidos y seguros.

