v19.2Latest

State bewahren und zurücksetzen

State ist zwischen Komponenten isoliert. React behält den Überblick darüber, welcher State zu welcher Komponente gehört, basierend auf deren Position im UI-Baum. Sie können steuern, wann der State zwischen erneuten Render-Vorgängen bewahrt oder zurückgesetzt wird.

Sie werden lernen
  • Wann React sich entscheidet, den State zu bewahren oder zurückzusetzen
  • Wie Sie React zwingen können, den State einer Komponente zurückzusetzen
  • Wie Keys und Typen beeinflussen, ob der State bewahrt wird

State ist an eine Position im Render-Baum gebunden

React erstelltRender-Bäumefür die Komponentenstruktur in Ihrer Benutzeroberfläche.

Wenn Sie einer Komponente State geben, denken Sie vielleicht, der State „lebe“ innerhalb der Komponente. Aber der State wird tatsächlich von React gehalten. React ordnet jedes Stück State, das es hält, der richtigen Komponente zu, basierend darauf, wo diese Komponente im Render-Baum sitzt.

Hier gibt es nur ein<Counter />JSX-Tag, aber es wird an zwei verschiedenen Positionen gerendert:

So sehen diese als Baum aus:

Diagramm eines Baums von React-Komponenten. Der Wurzelknoten ist mit 'div' beschriftet und hat zwei Kinder. Jedes der Kinder ist mit 'Counter' beschriftet und beide enthalten eine State-Blase mit der Beschriftung 'count' und dem Wert 0.Diagramm eines Baums von React-Komponenten. Der Wurzelknoten ist mit 'div' beschriftet und hat zwei Kinder. Jedes der Kinder ist mit 'Counter' beschriftet und beide enthalten eine State-Blase mit der Beschriftung 'count' und dem Wert 0.

React-Baum

Dies sind zwei separate Zähler, weil jeder an seiner eigenen Position im Baum gerendert wird.Sie müssen normalerweise nicht über diese Positionen nachdenken, um React zu verwenden, aber es kann nützlich sein zu verstehen, wie es funktioniert.

In React hat jede Komponente auf dem Bildschirm einen vollständig isolierten State. Wenn Sie beispielsweise zweiCounter-Komponenten nebeneinander rendern, erhält jede ihren eigenen, unabhängigenscore- undhover-State.

Versuchen Sie, beide Zähler zu klicken, und beachten Sie, dass sie sich nicht gegenseitig beeinflussen:

Wie Sie sehen können, wird bei der Aktualisierung eines Zählers nur der State für diese Komponente aktualisiert:

Diagramm eines Baums von React-Komponenten. Der Wurzelknoten ist mit 'div' beschriftet und hat zwei Kinder. Das linke Kind ist mit 'Counter' beschriftet und enthält eine State-Blase mit der Beschriftung 'count' und dem Wert 0. Das rechte Kind ist mit 'Counter' beschriftet und enthält eine State-Blase mit der Beschriftung 'count' und dem Wert 1. Die State-Blase des rechten Kindes ist gelb hervorgehoben, um anzuzeigen, dass ihr Wert aktualisiert wurde.Diagramm eines Baums von React-Komponenten. Der Wurzelknoten ist mit 'div' beschriftet und hat zwei Kinder. Das linke Kind ist mit 'Counter' beschriftet und enthält eine State-Blase mit der Beschriftung 'count' und dem Wert 0. Das rechte Kind ist mit 'Counter' beschriftet und enthält eine State-Blase mit der Beschriftung 'count' und dem Wert 1. Die State-Blase des rechten Kindes ist gelb hervorgehoben, um anzuzeigen, dass ihr Wert aktualisiert wurde.

State aktualisieren

React behält den State so lange, wie Sie dieselbe Komponente an derselben Position im Baum rendern. Um dies zu sehen, erhöhen Sie beide Zähler, entfernen Sie dann die zweite Komponente, indem Sie das Kontrollkästchen „Zweiten Zähler rendern“ deaktivieren, und fügen Sie sie dann wieder hinzu, indem Sie es erneut aktivieren:

Beachten Sie, wie der State des zweiten Zählers in dem Moment, in dem Sie ihn nicht mehr rendern, vollständig verschwindet. Das liegt daran, dass React, wenn es eine Komponente entfernt, ihren State zerstört.

Diagramm eines Baums von React-Komponenten. Der Wurzelknoten ist mit 'div' beschriftet und hat zwei Kinder. Das linke Kind ist mit 'Counter' beschriftet und enthält eine State-Blase mit der Beschriftung 'count' und dem Wert 0. Das rechte Kind fehlt, und an seiner Stelle befindet sich ein gelbes 'Puff'-Bild, das die Löschung der Komponente aus dem Baum hervorhebt.Diagramm eines Baums von React-Komponenten. Der Wurzelknoten ist mit 'div' beschriftet und hat zwei Kinder. Das linke Kind ist mit 'Counter' beschriftet und enthält eine Zustandsblase mit der Beschriftung 'count' und dem Wert 0. Das rechte Kind fehlt, und an seiner Stelle befindet sich ein gelbes 'Puff'-Bild, das die aus dem Baum gelöschte Komponente hervorhebt.

Löschen einer Komponente

Wenn Sie „Zweiten Counter rendern“ aktivieren, wird ein zweiterCounterund sein Zustand von Grund auf neu initialisiert (score = 0) und zum DOM hinzugefügt.

Diagramm eines Baums von React-Komponenten. Der Wurzelknoten ist mit 'div' beschriftet und hat zwei Kinder. Das linke Kind ist mit 'Counter' beschriftet und enthält eine Zustandsblase mit der Beschriftung 'count' und dem Wert 0. Das rechte Kind ist mit 'Counter' beschriftet und enthält eine Zustandsblase mit der Beschriftung 'count' und dem Wert 0. Der gesamte rechte Kindknoten ist gelb hervorgehoben, was anzeigt, dass er gerade zum Baum hinzugefügt wurde.Diagramm eines Baums von React-Komponenten. Der Wurzelknoten ist mit 'div' beschriftet und hat zwei Kinder. Das linke Kind ist mit 'Counter' beschriftet und enthält eine Zustandsblase mit der Beschriftung 'count' und dem Wert 0. Das rechte Kind ist mit 'Counter' beschriftet und enthält eine Zustandsblase mit der Beschriftung 'count' und dem Wert 0. Der gesamte rechte Kindknoten ist gelb hervorgehoben, was anzeigt, dass er gerade zum Baum hinzugefügt wurde.

Hinzufügen einer Komponente

React bewahrt den Zustand einer Komponente, solange sie an ihrer Position im UI-Baum gerendert wird.Wenn sie entfernt wird oder eine andere Komponente an derselben Position gerendert wird, verwirft React ihren Zustand.

Dieselbe Komponente an derselben Position bewahrt den Zustand

In diesem Beispiel gibt es zwei verschiedene<Counter />-Tags:

Wenn Sie das Kontrollkästchen aktivieren oder deaktivieren, wird der Zählerzustand nicht zurückgesetzt. Egal, obisFancy trueoderfalseist, Sie haben immer einen<Counter />als erstes Kind desdiv, das von der Root-App-Komponente zurückgegeben wird:

Diagramm mit zwei Abschnitten, die durch einen Pfeil getrennt sind, der einen Übergang zwischen ihnen darstellt. Jeder Abschnitt enthält ein Layout von Komponenten mit einem Elternteil mit der Bezeichnung 'App', das eine Zustandsblase mit der Bezeichnung isFancy enthält. Diese Komponente hat ein Kind mit der Bezeichnung 'div', das zu einer Prop-Blase führt, die isFancy enthält (violett hervorgehoben), die an das einzige Kind weitergegeben wird. Das letzte Kind ist mit 'Counter' beschriftet und enthält eine Zustandsblase mit der Beschriftung 'count' und dem Wert 3 in beiden Diagrammen. Im linken Abschnitt des Diagramms ist nichts hervorgehoben und der isFancy-Elternzustandswert ist false. Im rechten Abschnitt des Diagramms hat sich der isFancy-Elternzustandswert auf true geändert und ist gelb hervorgehoben, ebenso wie die darunter liegende Prop-Blase, die ihren isFancy-Wert ebenfalls auf true geändert hat.Diagramm mit zwei Abschnitten, die durch einen Pfeil getrennt sind, der einen Übergang zwischen ihnen darstellt. Jeder Abschnitt enthält ein Layout von Komponenten mit einem Elternteil mit der Bezeichnung 'App', das eine Zustandsblase mit der Bezeichnung isFancy enthält. Diese Komponente hat ein Kind mit der Bezeichnung 'div', das zu einer Prop-Blase führt, die isFancy enthält (violett hervorgehoben), die an das einzige Kind weitergegeben wird. Das letzte Kind ist mit 'Counter' beschriftet und enthält eine Zustandsblase mit der Beschriftung 'count' und dem Wert 3 in beiden Diagrammen. Im linken Abschnitt des Diagramms ist nichts hervorgehoben und der isFancy-Elternzustandswert ist false. Im rechten Abschnitt des Diagramms hat sich der isFancy-Elternzustandswert auf true geändert und ist gelb hervorgehoben, ebenso wie die darunter liegende Prop-Blase, die ihren isFancy-Wert ebenfalls auf true geändert hat.

Das Aktualisieren desApp-Zustands setzt denCounternicht zurück, weil derCounteran derselben Position bleibt

Es ist dieselbe Komponente an derselben Position, also ist es aus Sicht von React derselbe Zähler.

Fallstrick

Denken Sie daran, dassfür React die Position im UI-Baum – nicht im JSX-Markup – entscheidend ist!Diese Komponente hat zweireturn-Klauseln mit unterschiedlichen<Counter />-JSX-Tags innerhalb und außerhalb derif-Bedingung:

Sie könnten erwarten, dass der Zustand zurückgesetzt wird, wenn Sie das Kontrollkästchen aktivieren, aber das passiert nicht! Das liegt daran, dassbeide dieser<Counter />-Tags an derselben Position gerendert werden.React weiß nicht, wo Sie die Bedingungen in Ihrer Funktion platzieren. Alles, was es „sieht“, ist der Baum, den Sie zurückgeben.

In beiden Fällen gibt dieApp-Komponente ein<div>mit<Counter />als erstem Kind zurück. Für React haben diese beiden Zähler dieselbe „Adresse“: das erste Kind des ersten Kinds der Wurzel. So gleicht React sie zwischen vorherigem und nächstem Render ab, unabhängig davon, wie Sie Ihre Logik strukturieren.

Verschiedene Komponenten an derselben Position setzen den Zustand zurück

In diesem Beispiel ersetzt das Aktivieren des Kontrollkästchens<Counter>durch ein<p>:

Hier wechselst du zwischenverschiedenenKomponententypen an derselben Position. Ursprünglich enthielt das erste Kind des<div>einenCounter. Aber als du einpeingetauscht hast, entfernte React denCounteraus dem UI-Baum und zerstörte seinen Zustand.

Diagramm mit drei Abschnitten, wobei ein Pfeil zwischen jedem Abschnitt überleitet. Der erste Abschnitt enthält eine React-Komponente mit der Bezeichnung 'div' mit einem einzigen Kind mit der Bezeichnung 'Counter', das eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 3 enthält. Der mittlere Abschnitt hat denselben 'div'-Elternteil, aber die Kindkomponente wurde nun gelöscht, was durch ein gelbes 'proof'-Bild angezeigt wird. Der dritte Abschnitt hat wieder denselben 'div'-Elternteil, jetzt mit einem neuen Kind mit der Bezeichnung 'p', das gelb hervorgehoben ist.Diagramm mit drei Abschnitten, wobei ein Pfeil zwischen jedem Abschnitt überleitet. Der erste Abschnitt enthält eine React-Komponente mit der Bezeichnung 'div' mit einem einzigen Kind mit der Bezeichnung 'Counter', das eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 3 enthält. Der mittlere Abschnitt hat denselben 'div'-Elternteil, aber die Kindkomponente wurde nun gelöscht, was durch ein gelbes 'proof'-Bild angezeigt wird. Der dritte Abschnitt hat wieder denselben 'div'-Elternteil, jetzt mit einem neuen Kind mit der Bezeichnung 'p', das gelb hervorgehoben ist.

Wenn sichCounter in pändert, wird derCountergelöscht und dasphinzugefügt

Diagramm mit drei Abschnitten, wobei ein Pfeil zwischen jedem Abschnitt überleitet. Der erste Abschnitt enthält eine React-Komponente mit der Bezeichnung 'p'. Der mittlere Abschnitt hat denselben 'div'-Elternteil, aber die Kindkomponente wurde nun gelöscht, was durch ein gelbes 'proof'-Bild angezeigt wird. Der dritte Abschnitt hat wieder denselben 'div'-Elternteil, jetzt mit einem neuen Kind mit der Bezeichnung 'Counter', das eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 0 enthält, alles gelb hervorgehoben.Diagramm mit drei Abschnitten, wobei ein Pfeil zwischen jedem Abschnitt überleitet. Der erste Abschnitt enthält eine React-Komponente mit der Bezeichnung 'p'. Der mittlere Abschnitt hat denselben 'div'-Elternteil, aber die Kindkomponente wurde nun gelöscht, was durch ein gelbes 'proof'-Bild angezeigt wird. Der dritte Abschnitt hat wieder denselben 'div'-Elternteil, jetzt mit einem neuen Kind mit der Bezeichnung 'Counter', das eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 0 enthält, alles gelb hervorgehoben.

Beim Zurückschalten wird daspgelöscht und derCounterhinzugefügt

Außerdemsetzt das Rendern einer anderen Komponente an derselben Position den Zustand ihres gesamten Unterbaums zurück.Um zu sehen, wie das funktioniert, erhöhe den Zähler und setze dann das Häkchen:

Der Zählerzustand wird zurückgesetzt, wenn du das Häkchen setzt. Obwohl du einenCounterrenderst, ändert sich das erste Kind desdivvon einemsectionzu einemdiv. Als das Kindsectionaus dem DOM entfernt wurde, wurde der gesamte darunter liegende Baum (einschließlich desCounterund seines Zustands) ebenfalls zerstört.

Diagramm mit drei Abschnitten, wobei ein Pfeil zwischen jedem Abschnitt überleitet. Der erste Abschnitt enthält eine React-Komponente mit der Bezeichnung 'div' mit einem einzigen Kind mit der Bezeichnung 'section', das ein einzelnes Kind mit der Bezeichnung 'Counter' hat, das eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 3 enthält. Der mittlere Abschnitt hat denselben 'div'-Elternteil, aber die Kindkomponenten wurden nun gelöscht, was durch ein gelbes 'proof'-Bild angezeigt wird. Der dritte Abschnitt hat wieder denselben 'div'-Elternteil, jetzt mit einem neuen Kind mit der Bezeichnung 'div', gelb hervorgehoben, ebenfalls mit einem neuen Kind mit der Bezeichnung 'Counter', das eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 0 enthält, alles gelb hervorgehoben.Diagramm mit drei Abschnitten, wobei ein Pfeil zwischen jedem Abschnitt überleitet. Der erste Abschnitt enthält eine React-Komponente mit der Bezeichnung 'div' mit einem einzigen Kind mit der Bezeichnung 'section', das ein einzelnes Kind mit der Bezeichnung 'Counter' hat, das eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 3 enthält. Der mittlere Abschnitt hat denselben 'div'-Elternteil, aber die Kindkomponenten wurden nun gelöscht, was durch ein gelbes 'proof'-Bild angezeigt wird. Der dritte Abschnitt hat wieder denselben 'div'-Elternteil, jetzt mit einem neuen Kind mit der Bezeichnung 'div', gelb hervorgehoben, ebenfalls mit einem neuen Kind mit der Bezeichnung 'Counter', das eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 0 enthält, alles gelb hervorgehoben.

Wenn sichsection in divändert, wird diesectiongelöscht und das neuedivhinzugefügt

Diagramm mit drei Abschnitten, wobei ein Pfeil zwischen jedem Abschnitt überleitet. Der erste Abschnitt enthält eine React-Komponente mit der Bezeichnung 'div', die ein einzelnes Kind mit der Bezeichnung 'div' hat, welches wiederum ein einzelnes Kind mit der Bezeichnung 'Counter' enthält. Dieser Counter enthält eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 0. Der mittlere Abschnitt hat denselben 'div'-Elternteil, aber die Kindkomponenten wurden nun gelöscht, was durch ein gelbes 'proof'-Bild angezeigt wird. Der dritte Abschnitt hat wieder denselben 'div'-Elternteil, jetzt mit einem neuen Kind mit der Bezeichnung 'section', das gelb hervorgehoben ist, sowie einem neuen Kind mit der Bezeichnung 'Counter', das eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 0 enthält, alles gelb hervorgehoben.Diagramm mit drei Abschnitten, wobei ein Pfeil zwischen jedem Abschnitt überleitet. Der erste Abschnitt enthält eine React-Komponente mit der Bezeichnung 'div', die ein einzelnes Kind mit der Bezeichnung 'div' hat, welches wiederum ein einzelnes Kind mit der Bezeichnung 'Counter' enthält. Dieser Counter enthält eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 0. Der mittlere Abschnitt hat denselben 'div'-Elternteil, aber die Kindkomponenten wurden nun gelöscht, was durch ein gelbes 'proof'-Bild angezeigt wird. Der dritte Abschnitt hat wieder denselben 'div'-Elternteil, jetzt mit einem neuen Kind mit der Bezeichnung 'section', das gelb hervorgehoben ist, sowie einem neuen Kind mit der Bezeichnung 'Counter', das eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 0 enthält, alles gelb hervorgehoben.

Beim Zurückschalten wird dasdivgelöscht und das neuesectionhinzugefügt.

Als Faustregel gilt:Wenn Sie den Zustand zwischen erneuten Renderings erhalten möchten, muss die Struktur Ihres Baums von einem Rendering zum nächsten „übereinstimmen“.Wenn die Struktur unterschiedlich ist, wird der Zustand zerstört, da React den Zustand zerstört, wenn es eine Komponente aus dem Baum entfernt.

Fallstrick

Deshalb sollten Sie Komponentenfunktionsdefinitionen nicht verschachteln.

Hier ist die KomponentenfunktionMyTextField voninnerhalbMyComponent definiert:

Jedes Mal, wenn Sie auf die Schaltfläche klicken, verschwindet der Eingabezustand! Das liegt daran, dass für jedes Rendering vonandereMyTextField-Funktion erstellt wird. Sie rendern eineMyComponent eine andereKomponente an derselben Position, daher setzt React den gesamten darunterliegenden Zustand zurück. Dies führt zu Fehlern und Leistungsproblemen. Um dieses Problem zu vermeiden,deklarieren Sie Komponentenfunktionen immer auf der obersten Ebene und verschachteln Sie ihre Definitionen nicht.

Zustand an derselben Position zurücksetzen

Standardmäßig bewahrt React den Zustand einer Komponente, solange sie an derselben Position bleibt. Normalerweise ist das genau das, was Sie wollen, daher ist es sinnvoll als Standardverhalten. Manchmal möchten Sie jedoch den Zustand einer Komponente zurücksetzen. Betrachten Sie diese App, die es zwei Spielern ermöglicht, ihre Punktestände während jeder Runde zu verfolgen:

Derzeit bleibt der Punktestand erhalten, wenn Sie den Spieler wechseln. Die beidenCountererscheinen an derselben Position, daher sieht React sie alsdenselbenCounteran, dessenperson-Prop sich geändert hat.

Konzeptionell sollten sie in dieser App jedoch zwei separate Zähler sein. Sie mögen an derselben Stelle in der Benutzeroberfläche erscheinen, aber einer ist ein Zähler für Taylor und der andere ein Zähler für Sarah.

Es gibt zwei Möglichkeiten, den Zustand beim Wechsel zwischen ihnen zurückzusetzen:

  1. Komponenten an verschiedenen Positionen rendern
  2. Jeder Komponente miteine explizite Identität gebenkey

Option 1: Eine Komponente an verschiedenen Positionen rendern

Wenn Sie möchten, dass diese beidenCounterunabhängig voneinander sind, können Sie sie an zwei verschiedenen Positionen rendern:

  • Anfangs istisPlayerA true. Daher enthält die erste Position denCounter-Zustand und die zweite ist leer.
  • Wenn Sie auf die Schaltfläche „Nächster Spieler“ klicken, wird die erste Position geleert, aber die zweite enthält nun einenCounter.
Diagramm mit einem Baum von React-Komponenten. Das Elternteil ist mit 'Scoreboard' beschriftet und hat eine Zustandsblase mit der Bezeichnung isPlayerA und dem Wert 'true'. Das einzige Kind, links angeordnet, ist mit 'Counter' beschriftet und hat eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 0. Das gesamte linke Kind ist gelb hervorgehoben, was anzeigt, dass es hinzugefügt wurde.Diagramm mit einem Baum von React-Komponenten. Das Elternteil ist mit 'Scoreboard' beschriftet und hat eine Zustandsblase mit der Bezeichnung isPlayerA und dem Wert 'true'. Das einzige Kind, links angeordnet, ist mit 'Counter' beschriftet und hat eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 0. Das gesamte linke Kind ist gelb hervorgehoben, was anzeigt, dass es hinzugefügt wurde.

Ausgangszustand

Diagramm mit einem Baum von React-Komponenten. Das Elternteil ist mit 'Scoreboard' beschriftet und hat eine Zustandsblase mit der Bezeichnung isPlayerA und dem Wert 'false'. Die Zustandsblase ist gelb hervorgehoben, was anzeigt, dass sie sich geändert hat. Das linke Kind wurde durch ein gelbes 'Poof'-Bild ersetzt, was anzeigt, dass es gelöscht wurde, und es gibt ein neues Kind rechts, gelb hervorgehoben, was anzeigt, dass es hinzugefügt wurde. Das neue Kind ist mit 'Counter' beschriftet und enthält eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 0.Diagramm mit einem Baum von React-Komponenten. Das Elternteil ist mit 'Scoreboard' beschriftet und hat eine Zustandsblase mit der Bezeichnung isPlayerA und dem Wert 'false'. Die Zustandsblase ist gelb hervorgehoben, was anzeigt, dass sie sich geändert hat. Das linke Kind wurde durch ein gelbes 'Poof'-Bild ersetzt, was anzeigt, dass es gelöscht wurde, und es gibt ein neues Kind rechts, gelb hervorgehoben, was anzeigt, dass es hinzugefügt wurde. Das neue Kind ist mit 'Counter' beschriftet und enthält eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 0.

Klicken auf „weiter“

Diagramm mit einem Baum von React-Komponenten. Das Elternteil ist mit 'Scoreboard' beschriftet und hat eine Zustandsblase mit der Bezeichnung isPlayerA und dem Wert 'true'. Die Zustandsblase ist gelb hervorgehoben, was anzeigt, dass sie sich geändert hat. Es gibt ein neues Kind links, gelb hervorgehoben, was anzeigt, dass es hinzugefügt wurde. Das neue Kind ist mit 'Counter' beschriftet und enthält eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 0. Das rechte Kind wurde durch ein gelbes 'Poof'-Bild ersetzt, was anzeigt, dass es gelöscht wurde.Diagramm mit einem Baum von React-Komponenten. Das Elternteil ist mit 'Scoreboard' beschriftet und hat eine Zustandsblase mit der Bezeichnung isPlayerA und dem Wert 'true'. Die Zustandsblase ist gelb hervorgehoben, was anzeigt, dass sie sich geändert hat. Es gibt ein neues Kind links, gelb hervorgehoben, was anzeigt, dass es hinzugefügt wurde. Das neue Kind ist mit 'Counter' beschriftet und enthält eine Zustandsblase mit der Bezeichnung 'count' und dem Wert 0. Das rechte Kind wurde durch ein gelbes 'Poof'-Bild ersetzt, was anzeigt, dass es gelöscht wurde.

Erneutes Klicken auf „weiter“

Der Zustand jedesCounters wird jedes Mal zerstört, wenn er aus dem DOM entfernt wird. Deshalb setzen sie sich jedes Mal zurück, wenn Sie auf die Schaltfläche klicken.

Diese Lösung ist praktisch, wenn Sie nur wenige unabhängige Komponenten an derselben Stelle rendern. In diesem Beispiel haben Sie nur zwei, daher ist es kein Problem, beide separat im JSX zu rendern.

Option 2: Zustand mit einem Key zurücksetzen

Es gibt auch eine andere, allgemeinere Möglichkeit, den Zustand einer Komponente zurückzusetzen.

Vielleicht haben Siekeys schon bei derRendern von Listengesehen. Keys sind nicht nur für Listen! Sie können Keys verwenden, um React zwischen beliebigen Komponenten unterscheiden zu lassen. Standardmäßig verwendet React die Reihenfolge innerhalb des Elternteils („erster Zähler“, „zweiter Zähler“), um zwischen Komponenten zu unterscheiden. Aber mit Keys können Sie React mitteilen, dass dies nicht nur einersteroder einzweiterZähler ist, sondern ein bestimmter Zähler – zum BeispielTaylorsZähler. Auf diese Weise erkennt ReactTaylorsZähler, wo immer er im Baum erscheint!

In diesem Beispiel teilen sich die beiden<Counter />s keinen Zustand, obwohl sie im JSX an derselben Stelle erscheinen:

Das Wechseln zwischen Taylor und Sarah bewahrt den Zustand nicht. Das liegt daran, dassSie ihnen unterschiedlichekeys gegeben haben:

Die Angabe eineskeys weist React an, denkeyselbst als Teil der Position zu verwenden, anstatt ihrer Reihenfolge innerhalb des Elternteils. Deshalb sieht React sie, obwohl sie im JSX an derselben Stelle gerendert werden, als zwei verschiedene Zähler, und daher teilen sie sich niemals den Zustand. Jedes Mal, wenn ein Zähler auf dem Bildschirm erscheint, wird sein Zustand erstellt. Jedes Mal, wenn er entfernt wird, wird sein Zustand zerstört. Das Umschalten zwischen ihnen setzt ihren Zustand immer wieder zurück.

Hinweis

Denken Sie daran, dass Keys nicht global eindeutig sind. Sie geben nur die Positioninnerhalb des Elternteilsan.

Ein Formular mit einem Key zurücksetzen

Das Zurücksetzen des Zustands mit einem Key ist besonders nützlich bei der Arbeit mit Formularen.

In dieser Chat-App enthält die<Chat>-Komponente den Zustand der Texteingabe:

Versuchen Sie, etwas in das Eingabefeld einzugeben, und drücken Sie dann „Alice“ oder „Bob“, um einen anderen Empfänger auszuwählen. Sie werden feststellen, dass der Eingabezustand erhalten bleibt, weil die<Chat>-Komponente an derselben Position im Baum gerendert wird.

In vielen Apps mag dies das gewünschte Verhalten sein, aber nicht in einer Chat-App!Sie möchten nicht, dass der Benutzer aufgrund eines versehentlichen Klicks eine bereits eingegebene Nachricht an die falsche Person sendet. Um dies zu beheben, fügen Sie einenkeyhinzu:

Dies stellt sicher, dass beim Auswählen eines anderen Empfängers dieChat-Komponente von Grund auf neu erstellt wird, einschließlich jeglichen Zustands im darunterliegenden Baum. React wird auch die DOM-Elemente neu erstellen, anstatt sie wiederzuverwenden.

Das Wechseln des Empfängers löscht nun immer das Textfeld:

Deep Dive
Zustand für entfernte Komponenten erhalten

Zusammenfassung

  • React behält den Zustand, solange dieselbe Komponente an derselben Position gerendert wird.
  • Der Zustand wird nicht in JSX-Tags gespeichert. Er ist mit der Baumposition verknüpft, an der Sie diesen JSX platzieren.
  • Sie können einen Teilbaum zwingen, seinen Zustand zurückzusetzen, indem Sie ihm einen anderen Schlüssel geben.
  • Verschachteln Sie keine Komponentendefinitionen, sonst setzen Sie den Zustand versehentlich zurück.

Try out some challenges

Challenge 1 of 5:Fix disappearing input text #

This example shows a message when you press the button. However, pressing the button also accidentally resets the input. Why does this happen? Fix it so that pressing the button does not reset the input text.