¿Qué significa "levantar el estado" en React y en qué situación lo harías?
Ver respuesta — intenta responderla en voz alta primero
Levantar el estado es mover un estado desde un componente hijo hacia el padre común más cercano, para que varios componentes lo compartan. Lo haces cuando dos o más componentes hermanos necesitan leer o modificar el mismo dato.
En React los datos fluyen hacia abajo: un padre pasa información a sus hijos por props, y un hermano no puede leer directamente el estado de otro hermano. Cuando dos componentes necesitan estar sincronizados, la solución es que ninguno sea el dueño del dato: el dueño pasa a ser su ancestro común más cercano. Los puntos clave:
- El estado vive en el padre común más cercano, no más arriba de lo necesario.
- El padre pasa hacia abajo dos cosas: el valor actual y una función para actualizarlo.
- El hijo que "escribe" llama a esa función; el hijo que "lee" recibe el valor por props.
- Queda una sola fuente de la verdad (single source of truth) y los hermanos nunca se desincronizan.
import { useState } from "react";
type EntradaProps = { busqueda: string; onCambio: (valor: string) => void };
// Hijo que ESCRIBE: recibe el valor y la función para actualizarlo
function EntradaBusqueda({ busqueda, onCambio }: EntradaProps) {
return <input value={busqueda} onChange={(e) => onCambio(e.target.value)} />;
}
// Hijo que LEE: solo necesita el valor actual
function ListaResultados({ busqueda }: { busqueda: string }) {
const frutas = ["manzana", "pera", "mango", "melón"];
const filtradas = frutas.filter((fruta) => fruta.includes(busqueda));
return (
<ul>
{filtradas.map((fruta) => <li key={fruta}>{fruta}</li>)}
</ul>
);
}
// Padre común más cercano: aquí vive el estado compartido
export function Buscador() {
const [busqueda, setBusqueda] = useState("");
return (
<section>
<EntradaBusqueda busqueda={busqueda} onCambio={setBusqueda} />
<ListaResultados busqueda={busqueda} />
</section>
);
}
Duplicar el estado en cada hermano e intentar "sincronizarlos" a mano:
// MAL: cada hermano tiene su propia copia del dato
function EntradaBusqueda() {
const [busqueda, setBusqueda] = useState(""); // la lista nunca ve esto
return <input value={busqueda} onChange={(e) => setBusqueda(e.target.value)} />;
}
La corrección es borrar los estados duplicados y declararlo una sola vez en el padre, como en el ejemplo de arriba. Si te descubres copiando el mismo dato en dos useState, esa es la señal de que toca levantar el estado.
Levantar el estado significa mover el estado al padre común más cercano cuando dos componentes necesitan compartir el mismo dato. Como en React los datos fluyen hacia abajo, un hermano no puede leer el estado de otro. Lo que hago es declarar el estado en el padre y pasar hacia abajo el valor y una función para actualizarlo. Así mantengo una sola fuente de la verdad y los componentes no se desincronizan. Eso sí, lo subo solo hasta donde hace falta, no directo a la raíz de la app.
Crea un componente Semaforo con dos hijos sincronizados: Luz muestra el color actual y BotonCambiar lo avanza. El color es "verde" | "amarillo" | "rojo" y debe vivir en el padre.
Ver solución
import { useState } from "react";
type Color = "verde" | "amarillo" | "rojo";
const siguiente: Record<Color, Color> = {
verde: "amarillo",
amarillo: "rojo",
rojo: "verde",
};
function Luz({ color }: { color: Color }) {
return <p>La luz está en: {color}</p>;
}
function BotonCambiar({ onCambiar }: { onCambiar: () => void }) {
return <button onClick={onCambiar}>Cambiar luz</button>;
}
// El padre es el dueño del estado que ambos hijos comparten
export function Semaforo() {
const [color, setColor] = useState<Color>("verde");
return (
<div>
<Luz color={color} />
<BotonCambiar onCambiar={() => setColor(siguiente[color])} />
</div>
);
}