Compartir estado entre componentes
Hay ocasiones en las que quieres que el estado de dos componentes cambien siempre juntos. Para hacerlo, elimina el estado de los dos, muévelo al padre común más cercano y luego pásalo a través de props. Esto se conoce como elevar el estado (lifting state up), y es una de las cosas más comunes que harás al escribir código React.
Aprenderás
- Cómo compartir el estado entre componentes por elevación
- Qué son los componentes controlados y no controlados
Elevar el estado con un ejemplo
En este ejemplo, el componente padre Accordion renderiza dos componentes Panel:
AccordionPanelPanel
Cada componente Panel tiene un estado booleano ‘isActive’ que determina si su contenido es visible.
Presiona el botón Mostrar en ambos paneles:
import { useState } from 'react'; function Panel({ title, children }) { const [isActive, setIsActive] = useState(false); return ( <section className="panel"> <h3>{title}</h3> {isActive ? ( <p>{children}</p> ) : ( <button onClick={() => setIsActive(true)}> Mostrar </button> )} </section> ); } export default function Accordion() { return ( <> <h2>Alma Ata, Kazajistán</h2> <Panel title="Acerca de"> Con una población de unos 2 millones de habitantes, Alma Ata es la mayor ciudad de Kazajistán. De 1929 a 1997 fue su capital. </Panel> <Panel title="Etimología"> El nombre proviene de <span lang="kk-KZ">алма</span>, palabra en kazajo que significa "manzana" y suele traducirse como "lleno de manzanas". De hecho, se cree que la región que rodea a Alma Ata es el hogar ancestral de la manzana, y se considera que este fruto silvestre <i lang="la">Malus sieversii</i> es un candidato probable para el ancestro de la manzana doméstica moderna. </Panel> </> ); }
Observa que pulsar el botón de un panel no afecta al otro: son independientes.


Inicialmente, el estado isActive de cada Panel es false, por lo que ambos aparecen colapsados


Al hacer clic en cualquiera de los botones del Panel sólo se actualizará el estado isActive de ese Panel.
Pero ahora digamos que quieres cambiarlo para que solo se mantenga expandido un panel a la vez. Con ese diseño, al expandir el segundo panel se debería colapsar el primero. ¿Cómo lo harías?
Para coordinar estos dos paneles, es necesario “elevar su estado” a un componente padre en tres pasos:
- Remueve el estado de los componentes hijos.
- Transfiere los datos codificados desde el padre común.
- Añade estado al padre común y pasarlo hacia abajo junto con los controladores de eventos.
Esto permitirá que el componente Accordion coordine ambos Panel y sólo expanda uno a la vez.
Paso 1: Elimina el estado de los componentes hijos
Le darás el control de isActive del Panel a su componente padre. Esto significa que el componente padre pasará isActive al Panel como prop. Empieza por eliminar esta línea del componente Panel:
const [isActive, setIsActive] = useState(false);Y en su lugar, añade isActive a la lista de props del Panel:
function Panel({ title, children, isActive }) {Ahora el componente padre de Panel puede controlar isActive pasándolo como prop. A la inversa, el componente Panel ahora no tiene ningún control sobre el valor de isActive—¡ahora depende del componente padre!
Paso 2: Pasa los datos codificados desde el componente padre común
Para elevar el estado, debes localizar el componente padre común más cercano de ambos componentes hijos que deseas coordinar:
Accordion(padre común más cercano)PanelPanel
En este ejemplo, es el componente Accordion, dado que está por encima de ambos paneles y puede controlar sus props, se convertirá en la “fuente de la verdad” para saber qué panel está actualmente activo. Haz que el componente Accordion pase un valor codificado de isActive (por ejemplo, true) a ambos paneles:
import { useState } from 'react'; export default function Accordion() { return