Formularios en React para Principiantes
Formularios en React para Principiantes
Los formularios en React manejan los datos de forma especial porque React controla la interfaz. Hay dos formas principales: controlados y no controlados.
1. Formularios Controlados (Recomendados)
En los formularios controlados, React maneja el estado de cada campo del formulario.
Ejemplo Básico:
import { useState } from 'react';
function FormularioSimple() {
// Estado para almacenar el valor del input
const [nombre, setNombre] = useState('');
// Manejar el cambio en el input
const manejarCambio = (e) => {
setNombre(e.target.value);
};
// Manejar el envío del formulario
const manejarEnvio = (e) => {
e.preventDefault(); // Evita que la página se recargue
alert(`Hola, ${nombre}!`);
};
return (
<form onSubmit={manejarEnvio}>
<label>
Tu nombre:
<input
type="text"
value={nombre}
onChange={manejarCambio}
/>
</label>
<button type="submit">Enviar</button>
<p>Texto escrito: {nombre}</p>
</form>
);
}2. Formulario con Múltiples Campos
import { useState } from 'react';
function FormularioRegistro() {
// Estado para todos los campos
const [formData, setFormData] = useState({
nombre: '',
email: '',
password: '',
aceptaTerminos: false
});
// Manejar cambios en cualquier campo
const manejarCambio = (e) => {
const { name, value, type, checked } = e.target;
setFormData({
...formData, // Copiamos todos los valores anteriores
[name]: type === 'checkbox' ? checked : value
});
};
// Manejar envío
const manejarEnvio = (e) => {
e.preventDefault();
console.log('Datos enviados:', formData);
alert(`Registro exitoso para: ${formData.nombre}`);
};
return (
<form onSubmit={manejarEnvio} style={{ maxWidth: '400px', margin: '20px auto' }}>
<h2>Registro de Usuario</h2>
<div style={{ marginBottom: '15px' }}>
<label>Nombre completo: </label>
<input
type="text"
name="nombre"
value={formData.nombre}
onChange={manejarCambio}
style={{ width: '100%', padding: '8px' }}
/>
</div>
<div style={{ marginBottom: '15px' }}>
<label>Email: </label>
<input
type="email"
name="email"
value={formData.email}
onChange={manejarCambio}
style={{ width: '100%', padding: '8px' }}
/>
</div>
<div style={{ marginBottom: '15px' }}>
<label>Contraseña: </label>
<input
type="password"
name="password"
value={formData.password}
onChange={manejarCambio}
style={{ width: '100%', padding: '8px' }}
/>
</div>
<div style={{ marginBottom: '15px' }}>
<label>
<input
type="checkbox"
name="aceptaTerminos"
checked={formData.aceptaTerminos}
onChange={manejarCambio}
/>
Acepto los términos y condiciones
</label>
</div>
<button
type="submit"
style={{
padding: '10px 20px',
backgroundColor: '#4CAF50',
color: 'white',
border: 'none',
cursor: 'pointer'
}}
>
Registrarse
</button>
<div style={{ marginTop: '20px', padding: '10px', backgroundColor: '#f0f0f0' }}>
<h3>Datos del formulario:</h3>
<pre>{JSON.stringify(formData, null, 2)}</pre>
</div>
</form>
);
}3. Formulario con Validación
import { useState } from 'react';
function FormularioConValidacion() {
const [formData, setFormData] = useState({
email: '',
password: ''
});
const [errores, setErrores] = useState({});
const validarFormulario = () => {
const nuevosErrores = {};
if (!formData.email) {
nuevosErrores.email = 'El email es requerido';
} else if (!formData.email.includes('@')) {
nuevosErrores.email = 'Email inválido';
}
if (!formData.password) {
nuevosErrores.password = 'La contraseña es requerida';
} else if (formData.password.length < 6) {
nuevosErrores.password = 'La contraseña debe tener al menos 6 caracteres';
}
setErrores(nuevosErrores);
return Object.keys(nuevosErrores).length === 0;
};
const manejarCambio = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value
});
// Limpiar error cuando el usuario empieza a escribir
if (errores[name]) {
setErrores({
...errores,
[name]: ''
});
}
};
const manejarEnvio = (e) => {
e.preventDefault();
if (validarFormulario()) {
alert('Formulario enviado correctamente!');
// Aquí normalmente enviarías los datos a un servidor
}
};
return (
<form onSubmit={manejarEnvio} style={{ maxWidth: '400px', margin: '20px auto' }}>
<h2>Iniciar Sesión</h2>
<div style={{ marginBottom: '15px' }}>
<label>Email: </label>
<input
type="email"
name="email"
value={formData.email}
onChange={manejarCambio}
style={{
width: '100%',
padding: '8px',
border: errores.email ? '2px solid red' : '1px solid #ccc'
}}
/>
{errores.email && (
<p style={{ color: 'red', fontSize: '14px' }}>{errores.email}</p>
)}
</div>
<div style={{ marginBottom: '15px' }}>
<label>Contraseña: </label>
<input
type="password"
name="password"
value={formData.password}
onChange={manejarCambio}
style={{
width: '100%',
padding: '8px',
border: errores.password ? '2px solid red' : '1px solid #ccc'
}}
/>
{errores.password && (
<p style={{ color: 'red', fontSize: '14px' }}>{errores.password}</p>
)}
</div>
<button
type="submit"
style={{
padding: '10px 20px',
backgroundColor: '#2196F3',
color: 'white',
border: 'none',
cursor: 'pointer'
}}
>
Iniciar Sesión
</button>
</form>
);
}4. Formulario con Select y Textarea
import { useState } from 'react';
function FormularioCompleto() {
const [formulario, setFormulario] = useState({
pais: 'es',
comentarios: '',
genero: 'femenino'
});
const manejarCambio = (e) => {
const { name, value } = e.target;
setFormulario({
...formulario,
[name]: value
});
};
const manejarEnvio = (e) => {
e.preventDefault();
console.log('Datos finales:', formulario);
alert('Formulario enviado!');
};
return (
<form onSubmit={manejarEnvio} style={{ maxWidth: '500px', margin: '20px auto' }}>
<h2>Formulario Completo</h2>
<div style={{ marginBottom: '15px' }}>
<label>País: </label>
<select
name="pais"
value={formulario.pais}
onChange={manejarCambio}
style={{ width: '100%', padding: '8px' }}
>
<option value="es">España</option>
<option value="mx">México</option>
<option value="ar">Argentina</option>
<option value="co">Colombia</option>
</select>
</div>
<div style={{ marginBottom: '15px' }}>
<label>Género: </label><br />
<label>
<input
type="radio"
name="genero"
value="masculino"
checked={formulario.genero === 'masculino'}
onChange={manejarCambio}
/>
Masculino
</label>
<br />
<label>
<input
type="radio"
name="genero"
value="femenino"
checked={formulario.genero === 'femenino'}
onChange={manejarCambio}
/>
Femenino
</label>
<br />
<label>
<input
type="radio"
name="genero"
value="otro"
checked={formulario.genero === 'otro'}
onChange={manejarCambio}
/>
Otro
</label>
</div>
<div style={{ marginBottom: '15px' }}>
<label>Comentarios: </label>
<textarea
name="comentarios"
value={formulario.comentarios}
onChange={manejarCambio}
rows="4"
style={{ width: '100%', padding: '8px' }}
placeholder="Escribe tus comentarios aquí..."
/>
</div>
<button type="submit">Enviar</button>
<div style={{ marginTop: '20px', padding: '10px', backgroundColor: '#f5f5f5' }}>
<h4>Resumen:</h4>
<p><strong>País:</strong> {formulario.pais}</p>
<p><strong>Género:</strong> {formulario.genero}</p>
<p><strong>Comentarios:</strong> {formulario.comentarios || '(ninguno)'}</p>
</div>
</form>
);
}5. Hook Personalizado para Formularios (Opcional avanzado)
// Hook personalizado reutilizable
function useFormulario(valoresIniciales) {
const [valores, setValores] = useState(valoresIniciales);
const manejarCambio = (e) => {
const { name, value, type, checked } = e.target;
setValores({
...valores,
[name]: type === 'checkbox' ? checked : value
});
};
const resetear = () => {
setValores(valoresIniciales);
};
return [valores, manejarCambio, resetear];
}
// Componente que usa el hook personalizado
function FormularioConHookPersonalizado() {
const [formData, manejarCambio, resetear] = useFormulario({
usuario: '',
edad: ''
});
const manejarEnvio = (e) => {
e.preventDefault();
console.log('Datos:', formData);
alert(`Usuario: ${formData.usuario}, Edad: ${formData.edad}`);
};
return (
<form onSubmit={manejarEnvio}>
<input
type="text"
name="usuario"
placeholder="Usuario"
value={formData.usuario}
onChange={manejarCambio}
/>
<input
type="number"
name="edad"
placeholder="Edad"
value={formData.edad}
onChange={manejarCambio}
/>
<button type="submit">Enviar</button>
<button type="button" onClick={resetear}>Limpiar</button>
</form>
);
}Puntos Clave a Recordar:
Formularios Controlados: Usa
valueyonChangepara cada inputEvento onSubmit: Maneja el envío del formulario
e.preventDefault(): Siempre úsalo para evitar recarga de página
Múltiples campos: Usa el atributo
namepara identificarlosCheckboxes/Radios: Usa
checkeden lugar devalueSpread operator (
...): Esencial para actualizar estado sin perder otros valores
Para Empezar:
Te recomiendo copiar estos ejemplos en tu proyecto React y:
Primero prueba el FormularioSimple
Luego experimenta con el FormularioRegistro
Finalmente agrega validación con FormularioConValidacion
¡La práctica es clave! Comienza con formularios simples y ve agregando complejidad
Comentarios
Publicar un comentario