Concepto clave
Los formularios en aplicaciones móviles son la puerta de entrada para que los usuarios interactúen con tu app. Imagina un formulario como un cuestionario digital que recopila información estructurada, similar a cuando llenas una solicitud de empleo o registras datos en una aplicación bancaria. En React Native, los formularios no son elementos nativos como en HTML, sino que se construyen combinando componentes como TextInput, Button y TouchableOpacity.
La validación es el filtro de calidad que asegura que los datos ingresados cumplan con reglas específicas antes de ser procesados. Por ejemplo, verificar que un correo electrónico tenga un formato válido o que una contraseña tenga al menos 8 caracteres. Sin validaciones, tu app podría recibir datos incorrectos que causen errores en el backend o una mala experiencia de usuario.
Cómo funciona en la práctica
Para implementar un formulario en React Native con Expo, seguimos un flujo estructurado. Primero, definimos el estado que almacenará los valores de los campos usando useState de React. Luego, conectamos cada campo de entrada (TextInput) a este estado mediante el prop onChangeText. Finalmente, agregamos validaciones que se ejecutan al enviar el formulario o en tiempo real, mostrando mensajes de error cuando sea necesario.
Paso a paso: 1) Crear los estados para cada campo (ej. email, password). 2) Renderizar los TextInputs vinculados a esos estados. 3) Implementar funciones de validación (ej. validarEmail). 4) Mostrar errores condicionalmente. 5) Manejar el envío con una función que verifique todas las validaciones antes de proceder.
Codigo en accion
Aquí tienes un ejemplo básico de un formulario de login con validación de email y contraseña:
import React, { useState } from 'react'; import { View, TextInput, Button, Text, StyleSheet } from 'react-native'; export default function LoginForm() { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [errors, setErrors] = useState({}); const validateEmail = (email) => { const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return regex.test(email); }; const validateForm = () => { let newErrors = {}; if (!email) newErrors.email = 'El email es obligatorio'; else if (!validateEmail(email)) newErrors.email = 'Email inválido'; if (!password) newErrors.password = 'La contraseña es obligatoria'; else if (password.length < 6) newErrors.password = 'Mínimo 6 caracteres'; setErrors(newErrors); return Object.keys(newErrors).length === 0; }; const handleSubmit = () => { if (validateForm()) { console.log('Formulario válido:', { email, password }); // Aquí iría la lógica de envío (ej. API call) } }; return ( {errors.email && {errors.email}} {errors.password && {errors.password}}); } const styles = StyleSheet.create({ container: { padding: 20 }, input: { borderWidth: 1, borderColor: '#ccc', padding: 10, marginBottom: 10 }, error: { color: 'red', fontSize: 12 } });
Ahora, mejoramos este código usando Formik y Yup para manejo avanzado:
import React from 'react'; import { View, TextInput, Button, Text } from 'react-native'; import { Formik } from 'formik'; import * as yup from 'yup'; const validationSchema = yup.object().shape({ email: yup.string().email('Email inválido').required('El email es obligatorio'), password: yup.string().min(6, 'Mínimo 6 caracteres').required('La contraseña es obligatoria') }); export default function LoginFormFormik() { return ( console.log('Formulario válido:', values)} > {({ handleChange, handleBlur, handleSubmit, values, errors, touched }) => ( {touched.email && errors.email && {errors.email}} {touched.password && errors.password && {errors.password}})} ); }
Errores comunes
- No limpiar errores al corregir: Si un usuario corrige un campo, los mensajes de error deben desaparecer. Solución: Usar estados que se resetee en onChangeText o librerías como Formik que manejan esto automáticamente.
- Validación solo al enviar: Esperar hasta el envío para mostrar errores frustra al usuario. Solución: Implementar validación en tiempo real (onBlur) para feedback inmediato.
- Olvidar el teclado numérico: Para campos como teléfono, no usar keyboardType="numeric" puede llevar a entradas incorrectas. Solución: Asignar el keyboardType apropiado a cada TextInput.
- Manejo ineficiente del estado: Crear un estado por cada campo en formularios grandes hace el código difícil de mantener. Solución: Usar un objeto único para todos los campos o adoptar Formik.
- Ignorar accesibilidad: No agregar labels o placeholders claros dificulta el uso para personas con discapacidades. Solución: Siempre incluir accesibilidad con props como accessibilityLabel.
Checklist de dominio
- Puedo crear un formulario con al menos 3 campos usando useState y TextInput.
- Sé implementar validaciones básicas (requerido, formato email, longitud mínima) tanto en vanilla React como con Yup.
- He usado Formik para manejar estado y validaciones en un formulario complejo.
- Puedo mostrar mensajes de error condicionales y estilizados.
- Sé manejar el envío del formulario solo si pasa todas las validaciones.
- He probado mi formulario en ambos dispositivos (iOS y Android) para verificar el comportamiento del teclado.
- Puedo explicar la diferencia entre validación en tiempo real y al enviar, y cuándo usar cada una.
Crear un formulario de registro con validaciones avanzadas
En este ejercicio, construirás un formulario de registro para una app móvil que incluya validaciones robustas y manejo de estado eficiente. Sigue estos pasos:
- Configura el proyecto: Crea un nuevo proyecto Expo o usa uno existente. Instala las dependencias necesarias:
npm install formik yup. - Diseña el formulario: Crea un componente que tenga los siguientes campos: nombre (texto), email (email), teléfono (numérico), contraseña (segura), y confirmación de contraseña (segura). Usa TextInput para cada uno con placeholders descriptivos.
- Implementa el estado con Formik: Envuelve tu formulario en un componente Formik. Define initialValues con todos los campos vacíos.
- Agrega validaciones con Yup: Crea un schema de validación que incluya: nombre requerido, email válido, teléfono con exactamente 10 dígitos, contraseña de al menos 8 caracteres con una letra mayúscula y un número, y confirmación de contraseña que coincida con la contraseña.
- Muestra errores: Para cada campo, muestra mensajes de error solo después de que el usuario lo haya tocado (usando touched). Estiliza los errores en rojo.
- Maneja el envío: Al presionar un botón "Registrarse", valida el formulario. Si es válido, muestra un alert con los datos; si no, muestra los errores.
- Prueba en dispositivos: Ejecuta la app en un emulador o dispositivo real para verificar que el teclado se adapte (ej. numérico para teléfono).
Entrega: Un archivo .js con el componente completo y una captura de pantalla del formulario en acción.
Pistas- Usa regex en Yup para validar la complejidad de la contraseña, por ejemplo: .matches(/^(?=.*[A-Z])(?=.*\d)/, 'Debe tener una mayúscula y un número').
- Para la confirmación de contraseña, usa .oneOf([yup.ref('password')], 'Las contraseñas no coinciden') en Yup.
- Recuerda que Formik maneja touched automáticamente; accede a él en la función render props para mostrar errores condicionalmente.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.