So werden Sie mit React setState () in 10 Minuten zum Profi

Dieser Artikel richtet sich an Personen, die bereits ihre erste Herangehensweise an React hatten und als Anfänger Zweifel daran haben, wie es setStatefunktioniert und wie es richtig verwendet wird. Es sollte auch mittelständischen bis älteren Entwicklern helfen, sauberere und abstraktere Methoden zum Festlegen des Status zu verwenden und Funktionen höherer Ordnung zum Behandeln und abstrakten Status zu bringen.

Einfach lesen und Spaß haben!

Also schnapp dir eine Tasse Kaffee und lies weiter! ?

Grundlegende Konzepte von setState ()

Mit React Components können Sie die Benutzeroberfläche in unabhängige, wiederverwendbare Teile aufteilen, sodass Sie jedes Teil einzeln betrachten können.

Konzeptionell sind Komponenten wie JavaScript-Funktionen. Sie akzeptieren beliebige Eingaben (sogenannte „Requisiten“) und geben React-Elemente zurück, die beschreiben, was auf dem Bildschirm angezeigt werden soll.

Wenn Sie dem Benutzer die Möglichkeit geben möchten, etwas einzugeben oder die Variablen, die die Komponente als Requisiten empfängt, auf irgendeine Weise zu ändern, benötigen Sie diese setState.

Unabhängig davon, ob Sie eine Komponente als Funktion oder Klasse deklarieren, darf sie niemals ihre eigenen Requisiten ändern.

Alle Reaktionskomponentenmüssen sich in Bezug auf ihre Requisiten wie reine Funktionen verhalten. Dies bedeutet, dass Funktionen, die niemals versuchen, ihre Eingaben zu ändern, immer dasselbe Ergebnis für dieselben Eingaben zurückgeben.

Natürlich sind Anwendungsbenutzeroberflächen dynamisch und ändern sich im Laufe der Zeit. Deshalb statewurde geschaffen.

State Ermöglicht React-Komponenten, ihre Ausgabe im Laufe der Zeit als Reaktion auf Benutzeraktionen, Netzwerkantworten und alles andere zu ändern, ohne diese Regel zu verletzen.

Als Klassen definierte Komponenten verfügen über einige zusätzliche Funktionen. Der lokale Status ist eine Funktion, die nur für Klassenkomponenten verfügbar ist.

setState ist die mit der Bibliothek bereitgestellte API-Methode, mit der der Benutzer den Status im Laufe der Zeit definieren und bearbeiten kann.

Drei Faustregeln bei Verwendung von setState ()

Ändern Sie den Status nicht direkt

Statusaktualisierungen können asynchron sein

React kann aus Gründen der Leistung mehrere setState()Anrufe in einem einzigen Update stapeln.

Da this.props und this.statemöglicherweise asynchron aktualisiert werden, sollten Sie sich bei der Berechnung des nächsten Status nicht auf deren Werte verlassen.

Sie sollten diese Art der Manipulation immer mit einem funktionalen Ansatz durchführen, indem Sie das stateund liefern propsund das Neue statebasierend auf dem ersteren zurückgeben.

Statusaktualisierungen werden zusammengeführt

Wenn Sie aufrufen setState(), führt React das von Ihnen bereitgestellte Objekt in das aktuelle Objekt ein state.

Im folgenden Beispiel aktualisieren wir die Variable dogNeedsVaccinationunabhängig von den anderen stateVariablen.

Die Zusammenführung ist flach, sodass this.setState({ dogNeedsVaccination: true }) die anderen Variablen intakt bleiben und nur den Wert von ersetzen dogNeedsVaccination.

Respektieren Sie den Datenfluss und vermeiden Sie die Angabe der max

Daten fließen runter! Weder übergeordnete noch untergeordnete Komponenten können wissen, ob eine bestimmte Komponente zustandsbehaftet oder zustandslos ist, und es sollte ihnen egal sein, ob sie als Funktion oder Klasse definiert ist.

Deshalb statewird es oft als lokal oder gekapselt bezeichnet. Es ist nur für die Komponente zugänglich, die es besitzt und festlegt.

Wenn Sie setStateeine Requisite verwenden und diese in Ihrer Komponente verwenden, unterbrechen Sie den Fluss der Rendering-Requisiten. Wenn sich die an Ihre Komponente übergebene Requisite aus irgendeinem Grund in der übergeordneten Komponente geändert hat, wird das untergeordnete Element nicht automatisch magisch neu gerendert ?!

Schauen wir uns ein Beispiel an:

Hier haben Sie eine HomeKomponente, die alle 1000 ms eine magische Zahl generiert und in eine eigene setzt state.

Danach rendert es die Nummer und ruft drei ChildKomponenten (Geschwister) auf, die die magische Nummer erhalten, mit dem Ziel, sie mit drei verschiedenen Ansätzen anzuzeigen:

Erste Ansatz

Die Komponente ChildOfHomerespektiert den Kaskadenfluss der React-Requisiten und rendert die propsempfangenen Daten direkt , da das Ziel nur darin besteht, die magische Zahl anzuzeigen .

Zweiter Ansatz

Die Komponente ChildOfHomeBrotherempfängt die propsvon ihrem übergeordneten Element componentDidMountund setzt beim Aufrufen die magische Zahl in state. Dann rendert es das state.magicNumber.

Dieses Beispiel funktioniert nicht, da render()nicht bekannt ist, dass sich a prop geändert hat, sodass das erneute Rendern der Komponente nicht ausgelöst wird. Da die Komponente nicht mehr neu gerendert wird, componentDidMountwird sie nicht aufgerufen und die Anzeige wird nicht aktualisiert.

Dritter Ansatz

Wenn wir versuchen, es mit dem zweiten Ansatz zum Laufen zu bringen, denken wir normalerweise, dass etwas fehlt. Anstatt einen Schritt zurückzutreten, fügen wir dem Code immer wieder Dinge hinzu, damit er funktioniert!

In diesem dritten Ansatz haben wir hinzugefügt componentDidUpdate, um zu überprüfen, ob eine Änderung vorgenommen wurde props, um das erneute Rendern der Komponente auszulösen. Dies ist unnötig und führt zu unreinem Code. Es bringt auch Leistungskosten mit sich, die mit der Häufigkeit multipliziert werden, mit der wir dies in einer großen App tun, in der wir viele verkettete Komponenten und Nebenwirkungen haben.

Dies ist falsch, es sei denn, Sie müssen dem Benutzer erlauben, den empfangenen Requisitenwert zu ändern.

Wenn Sie den Requisitenwert nicht ändern müssen, versuchen Sie immer, die Dinge entsprechend dem Reaktionsfluss (Erster Ansatz) am Laufen zu halten.

Sie können eine funktionierende Webseite mit diesem Beispiel überprüfen, das ich in Glitch für Sie vorbereitet habe. Schauen Sie und haben Sie Spaß?

Schauen Sie sich auch den Code im Home.jsund HomeCodeCleaned.js(ohne HTML-Zeug) in meinem Repo zu diesem Artikel an.

So setzen Sie State

An diesem Punkt denke ich, ist es Zeit, uns die Hände schmutzig zu machen!

Lass uns ein bisschen damit spielen setStateund das verbessern! Folgen Sie einfach und holen Sie sich eine weitere Tasse Kaffee!

Erstellen wir ein kleines Formular zum Aktualisieren der Benutzerdaten:

Hier ist der Code für das obige Beispiel:

Wir setzen stateals Objekt und es gibt kein Problem, da unser aktueller Zustand nicht von unserem letzten Zustand abhängt.

Was ist, wenn wir ein weiteres Formularfeld erstellen, um den Nachnamen einzuführen und anzuzeigen?

Nett! Wir haben die handleFormChangeMethode abstrahiert , um alle Eingabefelder und verarbeiten zu können setState.

Was ist, wenn wir eine Umschalttaste hinzufügen, um die Daten als gültig oder ungültig zu markieren, und einen Zähler, um zu wissen, wie viele Änderungen wir am Status vorgenommen haben?

Ja! Wir rocken! Wir haben viel abstrahiert!

Hmmm… Nehmen wir an, ich möchte nicht, dass ein Kontrollkästchen die isValidVariable steuert , sondern eine einfache Umschalttaste.

Lassen Sie uns auch den Counter-Handler von dieser Methode trennen. Es funktioniert gut, aber in komplexeren Situationen, in denen React Stapel- / Gruppenänderungen vornehmen muss, ist es keine gute Richtlinie, sich auf die this.state.counterVariable zu verlassen, um eine weitere hinzuzufügen. Dieser Wert kann sich ändern, ohne dass Sie sich dessen bewusst sind.

Wir verwenden zum Zeitpunkt des Aufrufs der Operation eine flache Kopie davon, und zu diesem bestimmten Zeitpunkt wissen Sie nicht, ob der Wert dem entspricht, den Sie erwartet haben oder nicht!

Lass uns ein bisschen funktional gehen!

Okay - Wir haben die Abstraktion verloren, weil wir die Handler getrennt haben, aber das hat einen guten Grund!

Zu diesem Zeitpunkt behalten wir also die handleFormChangeÜbergabe eines Objekts an die setStateAPI-Methode bei. Aber die Methoden handleCounterund handleIsValidsind jetzt funktionsfähig und beginnen damit, den aktuellen Status zu erfassen und ihn dann abhängig von diesem Status in den nächsten zu ändern.

Dies ist die richtige Methode zum Ändern der stateVariablen, die vom vorherigen Status abhängen.

Was ist, wenn wir bei jeder Änderung console.log()Änderungen der firstNameund lastNameEingabeformulare angeben möchten ? Lass es uns versuchen!

Nett! Jedes Mal, wenn das handleFormChangeauftritt (was bedeutet, dass ein neuer Tastendruck erfolgt ist), wird die logFields()Methode aufgerufen und protokolliert den aktuellen Status in der Konsole!

Lassen Sie uns die Browserkonsole überprüfen:

Warten! Was ist hier passiert, Leute? Das Konsolenprotokoll ist eine Änderung vor der aktuellen Formulareingabe! Warum passiert das?

setState ist asynchron !!

Wir wussten das schon, aber jetzt sehen wir es mit unseren Augen! Was passiert dort? Werfen wir einen Blick auf die oben genannten handleFormChangeund logFieldsMethoden.

Die handleFormChangeMethode empfängt also den Ereignisnamen und den Wert und führt dann eine setStatedieser Daten aus. Dann ruft es das handleCounterauf, um die Zählerinformationen zu aktualisieren, und ruft am Ende die logFieldsMethode auf. Die logFieldsMethode greift nach currentStateund gibt 'Eduard' anstelle von 'Eduardo' zurück.

Die Sache ist: setStateist asynchron und handelt nicht im Moment. React erledigt seine Aufgabe und führt zuerst die logFieldsMethode aus, setStateum zur nächsten Ereignisschleife zu gelangen.

Aber wie können wir solche Situationen vermeiden?

Nun, die setStateAPI hat eine callbackMöglichkeit, diese Situation zu vermeiden:

Wenn wir möchten, dass das logFields()die letzten Änderungen berücksichtigt, die wir am Status vorgenommen haben, müssen wir es im Rückruf wie folgt aufrufen:

Okay, jetzt funktioniert es!

Wir sagen React: „Hey React! Beachten Sie, dass beim Aufrufen der logFieldsMethode die statebereits aktualisierte Methode in Ordnung sein soll. Ich vertraue dir! "

React sagt: „Okay Edo! Ich werde all diese setStateDinge erledigen, die ich normalerweise im Hinterhof mit dem Ding mache, und erst wenn ich damit fertig bin, rufe ich an logFields()! Cooler Mann! Entspannen!"

Und tatsächlich - es hat funktioniert!

Okay, alle zusammen! Zu diesem Zeitpunkt haben wir die größten Fallstricke von bewältigt setState.

Hast du den Mut, über die Mauer hinauszugehen? Schnapp dir eine Tasse Kaffee und lass uns richtig kauen ...

Lust auf SetState ()

Jetzt, da wir handleCounterund handleIsValidMethoden, und setState()mit Funktionen ausgedrückt, können wir den Zustand Update mit anderen Funktionen zusammenstellen ! Ich mag Komposition! Lassen Sie uns etwas Spaß haben!

Wir können die Logik innerhalb setStatezu einer Funktion außerhalb der Klassenkomponente bringen. Nennen wir es toggleIsValid. ☝️

Jetzt kann diese Funktion außerhalb der Klassenkomponente überall in Ihrer App ausgeführt werden.

Was ist, wenn wir eine Funktion höherer Ordnung verwenden?

Beeindruckend! Jetzt rufen wir die toggleIsValidFunktion nicht mehr auf. Wir rufen eine abstrakte Funktion höherer Ordnung auf, die aufgerufen wird, toggleKeyund übergeben einen Schlüssel (in diesem Fall eine Zeichenfolge).

Wie müssen wir die toggleIsValidFunktion jetzt ändern ?

Was?! Jetzt haben wir eine Funktion namens toggleKey, die a empfängt keyund eine neue Funktion zurückgibt, die den Status entsprechend der angegebenen Taste ändert.

Dies toggleKeykann in einer Bibliothek oder in einer Hilfsdatei sein. Es kann in vielen verschiedenen Kontexten aufgerufen werden, um den Status von allem, was Sie wollen, in das Gegenteil zu ändern.

Toll!

Machen wir dasselbe mit dem Inkrementzähler-Handler:

Ja! Es klappt! So nett. Lass uns jetzt verrückt werden ...

Den Mond schießen und zurückkommen

Was ist, wenn wir eine generische makeUpdaterFunktion erstellen , die die Transformationsfunktion empfängt, die Sie anwenden möchten, den Schlüssel übernimmt und die Statusfunktion zurückgibt, die den Status mit der Transformationsfunktion und dem Schlüssel verwaltet? Ein bisschen verwirrt? Lass uns gehen!

Ok, das reicht ... Lass uns hier aufhören. ?

Sie können den gesamten Code überprüfen, den wir in diesem GitHub-Repo erstellt haben.

Zu guter Letzt

Vergessen Sie nicht, den maximalen Verwendungszustand zu vermeiden und die React-Rendering-Requisiten-Kaskade zu respektieren.

Vergiss nicht, setStateist asynchron.

Vergessen Sie nicht setState, ein Objekt oder eine Funktion übernehmen zu können

Vergessen Sie nicht, dass Sie eine Funktion übergeben sollten, wenn Ihr nächster Status von Ihrem vorherigen Status abhängt.

Literaturverzeichnis

  1. Dokumentation reagieren
  2. Erreichen Sie Tech-Kurse von Ryan Florence, die ich wirklich empfehlen kann.

Vielen Dank!