Volver a React Básico

Estado y Eventos

El estado hace que los componentes sean dinámicos. Cuando el estado cambia, React vuelve a renderizar el componente.

useState

import { useState } from 'react'; function Contador() { const [cuenta, setCuenta] = useState(0); return ( <div> <p>Cuenta: {cuenta}</p> <button onClick={() => setCuenta(cuenta + 1)}>+</button> <button onClick={() => setCuenta(cuenta - 1)}>-</button> <button onClick={() => setCuenta(0)}>Reiniciar</button> </div> ); }

Estado con Objetos

interface DatosFormulario { nombre: string; correo: string; rol: string; } function FormularioUsuario() { const [formulario, setFormulario] = useState<DatosFormulario>({ nombre: "", correo: "", rol: "visitante", }); // Siempre crea un NUEVO objeto — no mutes el estado const manejarCambio = (campo: keyof DatosFormulario, valor: string) => { setFormulario(prev => ({ ...prev, [campo]: valor })); }; return ( <form> <input value={formulario.nombre} onChange={e => manejarCambio("nombre", e.target.value)} placeholder="Nombre" /> <input value={formulario.correo} onChange={e => manejarCambio("correo", e.target.value)} placeholder="Correo" /> <select value={formulario.rol} onChange={e => manejarCambio("rol", e.target.value)} > <option value="admin">Admin</option> <option value="visitante">Visitante</option> </select> </form> ); }

Actualizaciones Funcionales

// Usa la forma funcional cuando el nuevo estado depende del anterior function ListaTareas() { const [tareas, setTareas] = useState<string[]>([]); const agregarTarea = (texto: string) => { // Seguro — siempre usa el estado más reciente setTareas(prev => [...prev, texto]); }; const eliminarTarea = (indice: number) => { setTareas(prev => prev.filter((_, i) => i !== indice)); }; }

Manejo de Eventos

function DemoEventos() { const manejarClic = (evento: React.MouseEvent<HTMLButtonElement>) => { console.log("Clic en:", evento.clientX, evento.clientY); }; const manejarTecla = (evento: React.KeyboardEvent<HTMLInputElement>) => { if (evento.key === "Enter") { console.log("¡Enviar!"); } }; const manejarEnvio = (evento: React.FormEvent<HTMLFormElement>) => { evento.preventDefault(); // Manejar datos del formulario }; const manejarCambio = (evento: React.ChangeEvent<HTMLInputElement>) => { console.log(evento.target.value); }; return ( <form onSubmit={manejarEnvio}> <input onChange={manejarCambio} onKeyDown={manejarTecla} /> <button type="submit" onClick={manejarClic}>Enviar</button> </form> ); }

Elevar el Estado

// Cuando hermanos necesitan compartir estado, elevarlo al padre function ConvertidorTemperatura() { const [celsius, setCelsius] = useState(0); const fahrenheit = celsius * 9/5 + 32; return ( <div> <label> Celsius: <input type="number" value={celsius} onChange={e => setCelsius(Number(e.target.value))} /> </label> <label> Fahrenheit: <input type="number" value={fahrenheit} onChange={e => setCelsius((Number(e.target.value) - 32) * 5/9)} /> </label> </div> ); }

Importante: Las actualizaciones de estado son asíncronas. Para actualizaciones basadas en el estado anterior, siempre usa la forma de callback: setState(prev => ...).