v19.2Latest

Zustand zwischen Komponenten teilen

Manchmal möchten Sie, dass sich der Zustand zweier Komponenten immer gemeinsam ändert. Um dies zu erreichen, entfernen Sie den Zustand aus beiden, verschieben ihn zu ihrem nächsten gemeinsamen Elternteil und übergeben ihn dann über Props an sie. Dies wird alsAnheben des Zustands (Lifting State Up)bezeichnet und ist eine der häufigsten Aufgaben beim Schreiben von React-Code.

Sie werden lernen
  • Wie Sie Zustand zwischen Komponenten teilen, indem Sie ihn anheben
  • Was gesteuerte und ungesteuerte Komponenten sind

Zustand anheben – ein Beispiel

In diesem Beispiel rendert eine übergeordneteAccordion-Komponente zwei separatePanels:

  • Accordion
    • Panel
    • Panel

JedePanel-Komponente hat einen booleschenisActive-Zustand, der bestimmt, ob ihr Inhalt sichtbar ist.

Drücken Sie die Schaltfläche „Anzeigen“ für beide Panels:

Beachten Sie, dass das Drücken der Schaltfläche eines Panels das andere Panel nicht beeinflusst – sie sind unabhängig.

Diagramm, das einen Baum aus drei Komponenten zeigt: eine übergeordnete Komponente namens Accordion und zwei untergeordnete Komponenten namens Panel. Beide Panel-Komponenten enthalten isActive mit dem Wert false.Diagramm, das einen Baum aus drei Komponenten zeigt: eine übergeordnete Komponente namens Accordion und zwei untergeordnete Komponenten namens Panel. Beide Panel-Komponenten enthalten isActive mit dem Wert false.

Anfangs ist derPanel-isActive-Zustand jeweilsfalse, daher erscheinen beide eingeklappt

Das gleiche Diagramm wie zuvor, wobei das isActive des ersten untergeordneten Panel-Komponente hervorgehoben ist, was einen Klick mit dem isActive-Wert true anzeigt. Die zweite Panel-Komponente enthält weiterhin den Wert false.Das gleiche Diagramm wie zuvor, wobei das isActive des ersten untergeordneten Panel-Komponente hervorgehoben ist, was einen Klick mit dem isActive-Wert true anzeigt. Die zweite Panel-Komponente enthält weiterhin den Wert false.

Das Klicken auf die Schaltfläche einesPanels aktualisiert nur denPanel-isActive-Zustand dieses Panels allein

Aber nehmen wir nun an, Sie möchten es so ändern, dass zu jedem Zeitpunkt nur ein Panel ausgeklappt ist.Bei diesem Design sollte das Ausklappen des zweiten Panels das erste einklappen. Wie würden Sie das umsetzen?

Um diese beiden Panels zu koordinieren, müssen Sie ihren Zustand in drei Schritten zu einer übergeordneten Komponente „anheben“:

  1. EntfernenSie den Zustand aus den untergeordneten Komponenten.
  2. ÜbergebenSie hartcodierte Daten vom gemeinsamen Elternteil.
  3. FügenSie dem gemeinsamen Elternteil Zustand hinzu und übergeben Sie ihn zusammen mit den Event-Handlern nach unten.

Dies ermöglicht es derAccordion-Komponente, beidePanels zu koordinieren und jeweils nur eines auf einmal auszuklappen.

Schritt 1: Zustand aus den untergeordneten Komponenten entfernen

Sie werden die Kontrolle über dasPanel-isActivean seine übergeordnete Komponente abgeben. Das bedeutet, dass die übergeordnete KomponenteisActiveals Prop anPanelübergeben wird. Beginnen Sie damit,diese Zeileaus derPanel-Komponente zu entfernen:

Stattdessen fügen SieisActivezur Liste der Props desPanelhinzu:

Jetzt kann die übergeordnete Komponente vonPanelden Wert vonsteuernisActive, indem sie ihnals Prop weitergibt.Umgekehrt hat diePanel-Komponente jetztkeine Kontrolleüber den Wert vonisActive– das liegt nun bei der übergeordneten Komponente!

Schritt 2: Übergeben Sie hartcodierte Daten von der gemeinsamen Elternkomponente

Um den State anzuheben, müssen Sie die nächstgelegene gemeinsame ElternkomponentebeiderKindkomponenten lokalisieren, die Sie koordinieren möchten:

  • Accordion(nächstgelegene gemeinsame Elternkomponente)
    • Panel
    • Panel

In diesem Beispiel ist es dieAccordion-Komponente. Da sie über beiden Panels steht und ihre Props steuern kann, wird sie zur „Single Source of Truth“ dafür, welches Panel gerade aktiv ist. Lassen Sie dieAccordion-Komponente einen hartcodierten Wert fürisActive(zum Beispieltrue) an beide Panels übergeben:

Versuchen Sie, die hartcodiertenisActive-Werte in derAccordion-Komponente zu bearbeiten und sehen Sie das Ergebnis auf dem Bildschirm.

Schritt 3: Fügen Sie der gemeinsamen Elternkomponente State hinzu

Das Anheben des States ändert oft die Art dessen, was Sie als State speichern.

In diesem Fall sollte jeweils nur ein Panel aktiv sein. Das bedeutet, dass die gemeinsame ElternkomponenteAccordionim Auge behalten muss,welchesPanel das aktive ist. Anstatt einesboolean-Werts könnte sie eine Zahl als Index des aktivenPanelfür die State-Variable verwenden:

WennactiveIndex 0ist, ist das erste Panel aktiv, und wenn es1ist, ist es das zweite.

Ein Klick auf die Schaltfläche „Show“ in einem derPanels muss den aktiven Index inAccordionEinPanelkann denactiveIndex-State nicht direkt setzen, da er innerhalb vonAccordionDieAccordion-Komponente muss demPanel explizit erlauben, ihren State zu ändern, indem sieeinen Event-Handler als Prop weitergibt:

Die Schaltfläche<button>innerhalb vonPanelverwendet nun dieonShow-Prop als ihren Klick-Event-Handler:

Damit ist das Anheben des Zustands abgeschlossen! Das Verschieben des Zustands in die gemeinsame Elternkomponente ermöglichte es Ihnen, die beiden Panels zu koordinieren. Die Verwendung des aktiven Index anstelle von zwei "ist angezeigt"-Flags stellte sicher, dass zu einem bestimmten Zeitpunkt nur ein Panel aktiv ist. Und das Herunterreichen des Event-Handlers an das Kind erlaubte es dem Kind, den Zustand des Elternteils zu ändern.

Diagramm, das einen Baum aus drei Komponenten zeigt: eine Elternkomponente namens Accordion und zwei Kinderkomponenten namens Panel. Accordion enthält einen activeIndex-Wert von null, der in einen isActive-Wert von true für das erste Panel und einen isActive-Wert von false für das zweite Panel umgewandelt wird.Diagramm, das einen Baum aus drei Komponenten zeigt: eine Elternkomponente namens Accordion und zwei Kinderkomponenten namens Panel. Accordion enthält einen activeIndex-Wert von null, der in einen isActive-Wert von true für das erste Panel und einen isActive-Wert von false für das zweite Panel umgewandelt wird.

Anfangs ist derAccordion-activeIndex 0, daher erhält das erstePanel isActive = true

Das gleiche Diagramm wie zuvor, wobei der activeIndex-Wert der Elternkomponente Accordion hervorgehoben ist, was einen Klick mit dem geänderten Wert eins anzeigt. Der Fluss zu beiden Kinderkomponenten Panel ist ebenfalls hervorgehoben, und der an jedes Kind übergebene isActive-Wert ist auf das Gegenteil gesetzt: false für das erste Panel und true für das zweite.Das gleiche Diagramm wie zuvor, wobei der activeIndex-Wert der Elternkomponente Accordion hervorgehoben ist, was einen Klick mit dem geänderten Wert eins anzeigt. Der Fluss zu beiden Kinderkomponenten Panel ist ebenfalls hervorgehoben, und der an jedes Kind übergebene isActive-Wert ist auf das Gegenteil gesetzt: false für das erste Panel und true für das zweite.

Wenn sich derAccordion-activeIndex-Zustand in1ändert, erhält stattdessen das zweitePanel isActive = true

Deep Dive
Gestuerte und ungesteuerte Komponenten

Eine einzige Quelle der Wahrheit für jeden Zustand

In einer React-Anwendung haben viele Komponenten ihren eigenen Zustand. Einige Zustände "leben" nahe an den Blattkomponenten (Komponenten am unteren Ende des Baums), wie Eingabefelder. Andere Zustände "leben" näher an der Spitze der App. Selbst clientseitige Routing-Bibliotheken werden beispielsweise meist implementiert, indem die aktuelle Route im React-Zustand gespeichert und über Props nach unten weitergegeben wird!

Für jedes eindeutige Stück Zustand wählen Sie die Komponente aus, die ihn "besitzt".Dieses Prinzip ist auch als"Single Source of Truth" bekannt.Es bedeutet nicht, dass der gesamte Zustand an einem Ort lebt – sondern dass es fürjedesStück Zustand einespezifischeKomponente gibt, die diese Information hält. Anstatt gemeinsamen Zustand zwischen Komponenten zu duplizieren,heben Sie ihnin ihren gemeinsamen Elternteil an undgeben ihnan die Kinder weiter, die ihn benötigen.

Ihre App wird sich während der Arbeit ändern. Es ist üblich, dass Sie Zustand nach unten oder wieder nach oben verschieben, während Sie noch herausfinden, wo jedes Stück Zustand "lebt". Das ist alles Teil des Prozesses!

Um zu erfahren, wie sich das in der Praxis mit ein paar weiteren Komponenten anfühlt, lesen SieThinking in React.

Zusammenfassung

  • Wenn Sie zwei Komponenten koordinieren möchten, verschieben Sie ihren Zustand in ihren gemeinsamen Eltern.
  • Dann geben Sie die Informationen über Props vom gemeinsamen Eltern nach unten weiter.
  • Schließlich geben Sie Ereignishandler nach unten weiter, damit die Kinderkomponenten den Zustand des Eltern ändern können.
  • Es ist hilfreich, Komponenten als „gesteuert“ (durch Props angetrieben) oder „ungesteuert“ (durch Zustand angetrieben) zu betrachten.

Probieren Sie einige Herausforderungen aus

Challenge 1 of 2:Synced inputs #

Diese beiden Eingabefelder sind unabhängig. Sorgen Sie dafür, dass sie synchron bleiben: Die Bearbeitung eines Eingabefelds sollte das andere Eingabefeld mit demselben Text aktualisieren und umgekehrt.