Formularios y validación
El manejo de formularios y su validación son esenciales en muchas aplicaciones. En React, podemos manejar formularios de varias formas y, para validarlos, existen herramientas que simplifican la implementación y mejoran la experiencia del usuario.
1. Manejo de formularios en React #
En React, podemos manejar los formularios usando el estado. Cada campo de entrada puede actualizar el estado del componente en función de los cambios que realice el usuario.
Ejemplo de manejo básico de formularios:
1import React, { useState } from 'react'; 2 3function Formulario() { 4 const [nombre, setNombre] = useState(''); 5 const [email, setEmail] = useState(''); 6 7 const handleSubmit = (e) => { 8 e.preventDefault(); 9 console.log("Nombre:", nombre, "Email:", email); 10 }; 11 12 return ( 13 <form onSubmit={handleSubmit}> 14 <label> 15 Nombre: 16 <input type="text" value={nombre} onChange={(e) => setNombre(e.target.value)} /> 17 </label> 18 <br /> 19 <label> 20 Email: 21 <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} /> 22 </label> 23 <br /> 24 <button type="submit">Enviar</button> 25 </form> 26 ); 27} 28 29export default Formulario;
En este ejemplo:
- Cada campo de entrada tiene su propio estado (
nombreyemail) que se actualiza con el eventoonChange. handleSubmitevita que el formulario recargue la página y muestra los datos ingresados en la consola.
2. Validación de formularios #
La validación en React puede hacerse manualmente, comprobando si los campos cumplen ciertas condiciones antes de enviar el formulario. Esto se puede hacer con funciones condicionales en handleSubmit.
Ejemplo de validación manual:
1const handleSubmit = (e) => { 2 e.preventDefault(); 3 if (!nombre) { 4 alert("El nombre es obligatorio"); 5 return; 6 } 7 if (!email.includes("@")) { 8 alert("El email debe ser válido"); 9 return; 10 } 11 console.log("Formulario enviado con éxito"); 12};
En este caso:
- Si
nombreestá vacío oemailno contiene@, se muestra un mensaje de error y no se envía el formulario.
3. Librerías de validación (Formik y Yup) #
Para formularios más complejos, podemos usar Formik y Yup para simplificar la validación. Formik maneja el estado del formulario y la lógica de envío, mientras que Yup permite definir esquemas de validación de forma sencilla.
Instalación de Formik y Yup:
1npm install formik yup
Ejemplo de Formulario con Formik y Yup:
1import React from 'react'; 2import { useFormik } from 'formik'; 3import * as Yup from 'yup'; 4 5function FormularioDeRegistro() { 6 const formik = useFormik({ 7 initialValues: { 8 nombre: '', 9 email: '', 10 password: '', 11 }, 12 validationSchema: Yup.object({ 13 nombre: Yup.string() 14 .max(15, "Debe tener 15 caracteres o menos") 15 .required("El nombre es obligatorio"), 16 email: Yup.string() 17 .email("Email inválido") 18 .required("El email es obligatorio"), 19 password: Yup.string() 20 .min(6, "Debe tener al menos 6 caracteres") 21 .required("La contraseña es obligatoria"), 22 }), 23 onSubmit: (values) => { 24 console.log("Formulario enviado:", values); 25 }, 26 }); 27 28 return ( 29 <form onSubmit={formik.handleSubmit}> 30 <label> 31 Nombre: 32 <input 33 type="text" 34 name="nombre" 35 value={formik.values.nombre} 36 onChange={formik.handleChange} 37 onBlur={formik.handleBlur} 38 /> 39 </label> 40 {formik.touched.nombre && formik.errors.nombre ? ( 41 <div>{formik.errors.nombre}</div> 42 ) : null} 43 44 <label> 45 Email: 46 <input 47 type="email" 48 name="email" 49 value={formik.values.email} 50 onChange={formik.handleChange} 51 onBlur={formik.handleBlur} 52 /> 53 </label> 54 {formik.touched.email && formik.errors.email ? ( 55 <div>{formik.errors.email}</div> 56 ) : null} 57 58 <label> 59 Contraseña: 60 <input 61 type="password" 62 name="password" 63 value={formik.values.password} 64 onChange={formik.handleChange} 65 onBlur={formik.handleBlur} 66 /> 67 </label> 68 {formik.touched.password && formik.errors.password ? ( 69 <div>{formik.errors.password}</div> 70 ) : null} 71 72 <button type="submit">Registrarse</button> 73 </form> 74 ); 75} 76 77export default FormularioDeRegistro;
En este ejemplo:
initialValuesestablece los valores iniciales de cada campo.validationSchemautiliza Yup para definir las reglas de validación:nombredebe tener un máximo de 15 caracteres y es obligatorio.emaildebe ser un email válido y obligatorio.passworddebe tener al menos 6 caracteres y es obligatoria.
onSubmitmaneja el envío de los datos.
Cada campo tiene:
value,onChange, yonBlurconectados con Formik para manejar el estado y validación en tiempo real.- Errores mostrados cuando el usuario interactúa con el campo (
formik.touchedyformik.errors).
4. Ejercicio práctico: Formulario de registro con validación #
Vamos a crear un Formulario de Registro que use Formik y Yup para validar el nombre, email y contraseña.
1import React from 'react'; 2import { useFormik } from 'formik'; 3import * as Yup from 'yup'; 4 5function FormularioDeRegistro() { 6 const formik = useFormik({ 7 initialValues: { 8 nombre: '', 9 email: '', 10 password: '', 11 }, 12 validationSchema: Yup.object({ 13 nombre: Yup.string() 14 .required("Por favor ingrese su nombre") 15 .max(20, "El nombre no debe superar los 20 caracteres"), 16 email: Yup.string() 17 .email("Por favor ingrese un email válido") 18 .required("El email es obligatorio"), 19 password: Yup.string() 20 .min(8, "La contraseña debe tener al menos 8 caracteres") 21 .required("La contraseña es obligatoria"), 22 }), 23 onSubmit: (values) => { 24 alert("Registro exitoso"); 25 console.log("Datos enviados:", values); 26 }, 27 }); 28 29 return ( 30 <form onSubmit={formik.handleSubmit}> 31 <label htmlFor="nombre">Nombre:</label> 32 <input 33 id="nombre" 34 name="nombre" 35 type="text" 36 value={formik.values.nombre} 37 onChange={formik.handleChange} 38 onBlur={formik.handleBlur} 39 /> 40 {formik.touched.nombre && formik.errors.nombre ? ( 41 <div>{formik.errors.nombre}</div> 42 ) : null} 43 44 <label htmlFor="email">Email:</label> 45 <input 46 id="email" 47 name="email" 48 type="email" 49 value={formik.values.email} 50 onChange={formik.handleChange} 51 onBlur={formik.handleBlur} 52 /> 53 {formik.touched.email && formik.errors.email ? ( 54 <div>{formik.errors.email}</div> 55 ) : null} 56 57 <label htmlFor="password">Contraseña:</label> 58 <input 59 id="password" 60 name="password" 61 type="password" 62 value={formik.values.password} 63 onChange={formik.handleChange} 64 onBlur={formik.handleBlur} 65 /> 66 {formik.touched.password && formik.errors.password ? ( 67 <div>{formik.errors.password}</div> 68 ) : null} 69 70 <button type="submit">Registrarse</button> 71 </form> 72 ); 73} 74 75export default FormularioDeRegistro;
Resumen del tema
Conceptos clave #
- Manejo de Formularios con Estado Local: inputs controlados sincronizados con
useStatey validaciones manuales antes delonSubmit. - Librería Formik: hook
useFormikque gestiona automáticamente valores (values), eventos (handleChange,handleBlur), estado de interacción (touched) y envío (handleSubmit). - Validación con Esquemas (Yup / Zod): declaración declarativa de reglas de validación (
validationSchema: Yup.object({...})) con mensajes de error personalizados. - Experiencia de Usuario (UX): mostrar errores únicamente cuando el campo ha sido tocado/desenfocado (
touched.campo && errors.campo).
Qué debes recordar #
Formik y Yup/Zod simplifican la gestión de formularios complejos integrando validación declarativa por esquemas y control de errores por campo.