Ejercicio: Formularios y componentes controlados
Objetivo
Construir un formulario de registro controlado con validación, vista previa en vivo y mensaje de confirmación.
Cómo se trabaja
Escribe un componente llamado App (puedes crear los demás que necesites). Prueba tu código en el editor de abajo; cuando funcione, pega todo el archivo en el comprobador. Los import de react se aceptan y se ignoran, porque aquí React ya está cargado.
Pasos
Marca cada paso a medida que lo completes. Tu avance se guarda en este navegador.
💡 Pista 1: un solo objeto
Guarda { nombre: "", correo: "", acepto: false } y usa un único cambiar(e) que distinga entre checked y value según e.target.type.
💡 Pista 2: guardar el nombre
Antes de vaciar el formulario guarda el nombre en otro estado (creada) para poder mostrarlo en el mensaje.
🔎 Comprueba tu trabajo
Pega tu código y pulsa Comprobar. La revisión ocurre en tu navegador; nada se envía a ningún sitio. Cada punto en rojo incluye una pista.
✅ Ver una solución posible
Intenta resolverlo antes de mirar. Tu versión puede ser distinta y también correcta.
import { useState } from "react";
const vacio = { nombre: "", correo: "", acepto: false };
export default function App() {
const [datos, setDatos] = useState(vacio);
const [creada, setCreada] = useState("");
function cambiar(e) {
const { name, type, value, checked } = e.target;
setDatos({ ...datos, [name]: type === "checkbox" ? checked : value });
}
const valido = datos.nombre.trim() !== "" && datos.correo.includes("@") && datos.acepto;
function enviar(e) {
e.preventDefault();
setCreada(datos.nombre);
setDatos(vacio);
}
return (
<main>
<form onSubmit={enviar}>
<input name="nombre" value={datos.nombre} onChange={cambiar} placeholder="Nombre" />
<input name="correo" type="email" value={datos.correo} onChange={cambiar} placeholder="Correo" />
<label>
<input name="acepto" type="checkbox" checked={datos.acepto} onChange={cambiar} /> Acepto los términos
</label>
<button type="submit" disabled={!valido}>Crear cuenta</button>
</form>
<p className="vista">Hola, {datos.nombre || "desconocida"}</p>
{creada && <p role="status">Cuenta creada para {creada}</p>}
</main>
);
}
💡 🏁 Reto extra (opcional)
Añade un campo «Contraseña» con un indicador de fuerza (débil, media, fuerte) calculado según su longitud y si mezcla letras y números.