Patrones de actualizacion de estado
Actualizacion basada en valor anterior
function Contador() {
const [count, setCount] = useState(0);
// MAL - puede fallar con multiples clicks rapidos
const incrementarMal = () => {
setCount(count + 1);
};
// BIEN - usa el valor anterior
const incrementarBien = () => {
setCount(prev => prev + 1);
};
// Incrementar 3 veces
const incrementar3 = () => {
setCount(prev => prev + 1);
setCount(prev => prev + 1);
setCount(prev => prev + 1);
};
return (
<button onClick={incrementar3}>
Count: {count}
</button>
);
}
Actualizando objetos
function Formulario() {
const [form, setForm] = useState({
nombre: '',
email: '',
edad: 0
});
// MAL - muta el estado
const handleChangeMal = (e) => {
form.nombre = e.target.value; // NO!
};
// BIEN - crea nuevo objeto
const handleChange = (e) => {
setForm({
...form, // copia propiedades existentes
[e.target.name]: e.target.value // actualiza una
});
};
return (
<form>
<input
name="nombre"
value={form.nombre}
onChange={handleChange}
/>
<input
name="email"
value={form.email}
onChange={handleChange}
/>
</form>
);
}
Actualizando arrays
function ListaTareas() {
const [tareas, setTareas] = useState(['Estudiar', 'Ejercicio']);
// Agregar
const agregar = (tarea) => {
setTareas([...tareas, tarea]);
};
// Eliminar
const eliminar = (index) => {
setTareas(tareas.filter((_, i) => i !== index));
};
// Actualizar uno
const actualizar = (index, nuevoValor) => {
setTareas(tareas.map((t, i) =>
i === index ? nuevoValor : t
));
};
return (
<ul>
{tareas.map((tarea, i) => (
<li key={i}>
{tarea}
<button onClick={() => eliminar(i)}>X</button>
</li>
))}
</ul>
);
}
Estado con objetos anidados
const [user, setUser] = useState({
nombre: 'Maria',
direccion: {
ciudad: 'Madrid',
codigo: '28001'
}
});
// Actualizar propiedad anidada
const cambiarCiudad = (ciudad) => {
setUser({
...user,
direccion: {
...user.direccion,
ciudad: ciudad
}
});
};