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 => ...).