Compartir estado: elevar y Context
💡 🎯 Al terminar esta lección podrás…
- Elevar el estado cuando dos componentes lo comparten.
- Reconocer el prop drilling.
- Crear y consumir un contexto.
- Elegir entre estado local, elevado o Context.
1.Elevar el estado: el ancestro común
Cuando dos componentes necesitan el mismo dato, ninguno de los dos puede guardarlo (el estado de uno no es visible para el otro). La solución es elevar el estado al ancestro común más cercano y bajarlo a cada hijo mediante props. Si un hijo debe modificarlo, el padre le pasa también una función.
datos + funciones por propscomparte con- Identifica quién necesita el dato (
EntradayVista). - Sube el estado a su ancestro común (
App). - Baja el valor como prop (
texto) y el modo de cambiarlo como función (onCambio).
📌 Nota · El nombre onAlgo
Por convención, las props que reciben funciones para avisar de eventos se llaman onCambio, onGuardar, onBorrar… y las funciones que las manejan en el padre, manejarCambio, guardar, etc.
2.El problema: pasar props por muchos niveles
Elevar el estado funciona muy bien, pero si el dato debe viajar a través de muchos componentes intermedios que no lo usan, terminas escribiendo la misma prop en cada nivel. A eso se le llama prop drilling (perforar con props):
<App> // tiene el tema
<Pagina tema={tema}> // no lo usa, solo lo pasa
<Barra tema={tema}> // no lo usa, solo lo pasa
<Boton tema={tema} /> // ¡el único que lo usa!
</Barra>
</Pagina>
</App>
Para datos globales a una zona de la aplicación (el tema, el usuario conectado, el idioma, el carrito) React ofrece Context.
3.Context: datos disponibles para todo un árbol
Un contexto es un «canal» por el que un componente proveedor publica un valor, y cualquier descendiente, sin importar la profundidad, puede leerlo directamente. Se hace en tres pasos:
- Crear el contexto:
const TemaContext = createContext("claro"); - Proveer el valor:
<TemaContext.Provider value={...}> … </TemaContext.Provider> - Consumir el valor donde haga falta:
const tema = useContext(TemaContext);
📌 Nota · Cuando el valor cambia
Cuando el valor del Provider cambia, todos los componentes que lo leen con useContext se vuelven a dibujar. Por eso conviene que el contexto contenga datos que cambian poco, o dividirlo en varios contextos pequeños.
4.Un proveedor propio con estado y funciones
Lo más habitual es empaquetar el estado, el contexto y el proveedor en un componente propio, y un hook personalizado para consumirlo. Así el resto de la aplicación solo escribe useTema():
💡 Consejo · Comprobación útil
El throw del hook te avisa con un mensaje claro si olvidas envolver tus componentes en el proveedor, en vez de dejarte un undefined difícil de entender.
5.¿Estado local, elevado o Context?
| Situación | Mejor opción |
|---|---|
| Solo lo usa un componente | Estado local (useState en ese componente) |
| Lo usan un padre y sus hijos cercanos | Elevar el estado y pasar props |
| Lo necesitan muchos componentes lejanos (tema, usuario, idioma, carrito) | Context |
| Estado muy grande y complejo con muchas acciones | Context + useReducer (lección 9) o una biblioteca (Zustand, Redux Toolkit) |
| Datos del servidor (listas, perfiles) | Una biblioteca de datos (TanStack Query) o un hook propio (lección 10) |
⚠️ Importante · No te precipites con Context
Empieza siempre por lo más simple: estado local. Eleva el estado cuando haga falta. Usa Context cuando el prop drilling sea realmente molesto. Un contexto para todo vuelve la aplicación difícil de seguir.
6.Errores frecuentes
- Guardar el mismo dato en dos lugares: acaban desincronizados. Una sola fuente de verdad.
- Elevar el estado demasiado alto: súbelo solo hasta el ancestro común, no hasta
Apppor costumbre. - Usar
useContextfuera delProvider: recibes el valor por defecto (createContext(valor)), a vecesundefined. - Pasar un objeto nuevo como
valueen cada dibujo cuando no hace falta: todos los consumidores se redibujan. - Mutar el valor del contexto: cámbialo siempre mediante el estado del proveedor.
- Crear el contexto dentro de un componente: debe vivir fuera, a nivel de módulo.
- Olvidar
childrenen el proveedor propio: nada se dibuja dentro.
📒 Apuntes para llevar
- Si dos componentes necesitan el mismo dato, eleva el estado a su ancestro común.
- El padre pasa el valor y una función para modificarlo (
onCambio) por props. - Prop drilling: pasar props por niveles que no las usan; se soluciona con Context.
- Context:
createContext→<Context.Provider value>→useContext. - El patrón habitual: Provider propio con estado + hook
useAlgo()para consumirlo. - Empieza por estado local; sube o usa Context solo cuando hace falta.
- Una sola fuente de verdad para cada dato.
7.Glosario
| Término | Significado |
|---|---|
| Elevar el estado | Mover el estado al ancestro común para que varios hijos lo compartan. |
| Prop drilling | Pasar una prop por muchos componentes intermedios que no la necesitan. |
| Context | Mecanismo para publicar un valor que cualquier descendiente puede leer. |
| Provider | Componente que ofrece el valor de un contexto a su árbol. |
useContext | Hook que lee el valor del contexto más cercano. |
| Fuente de verdad | El único lugar donde vive un dato; los demás lo reciben. |
🧠 Comprueba lo aprendido
Elige una respuesta en cada pregunta. Verás al instante si acertaste y por qué.
Dos componentes hermanos necesitan el mismo dato. ¿Dónde guardas el estado?
Se eleva al ancestro común y se baja por props.
¿Qué es el prop drilling?
Es repetir una prop por muchos niveles solo para que llegue a un componente profundo.
¿Qué hace useContext(TemaContext)?
Devuelve el value del Provider más cercano por encima.
¿Dónde se define createContext?
Si lo creas dentro, se crearía uno nuevo en cada dibujo.
Un dato solo lo usa un componente. ¿Qué eliges?
Empieza por lo más simple: useState en ese componente.
Tu progreso se guarda en este navegador y se refleja en el índice del curso.
💡 🚀 ¡Ahora te toca!
La práctica fija lo aprendido. Pasa al ejercicio de esta lección.