
Hallo habrozhiteli! Die Originalausgabe wurde im Herbst 2017 veröffentlicht, gilt aber immer noch als das beste Buch zur Erkundung von React. Der Autor aktualisiert und modifiziert ständig den Code für das Buch im
Github- Repository.
Wir schlagen in einem Beitrag vor, sich mit der Passage "Staaten und ihre Rolle in der interaktiven Natur von React" vertraut zu machen.
Wenn Sie nur ein Kapitel in diesem Buch lesen mussten, sollten Sie dieses auswählen! Ohne Zustände bleiben React-Komponenten nichts anderes als erweiterte statische Muster. Ich hoffe, Sie teilen meine Begeisterung, denn wenn Sie die Konzepte in diesem Kapitel verstehen, können Sie viel interessantere Anwendungen erstellen.
Stellen Sie sich vor, Sie erstellen ein Eingabefeld mit automatischer Vervollständigung (Abb. 4.1). Bei der Eingabe von Daten sollte das Feld eine Anfrage an den Server senden, um Informationen zu geeigneten Optionen für die Anzeige der Ausgabe auf einer Webseite zu erhalten. Sie haben bisher mit Eigenschaften gearbeitet und wissen, dass Sie durch Ändern von Eigenschaften unterschiedliche Ansichten erhalten. Eigenschaften können jedoch nicht im Kontext der aktuellen Komponente geändert werden, da sie beim Erstellen der Komponente übergeben werden.

Mit anderen Worten, die Eigenschaften sind in der aktuellen Komponente unveränderlich. Dies bedeutet, dass Sie die Eigenschaften in dieser Komponente nur ändern können, wenn Sie die Komponente neu erstellen und die neuen Werte vom übergeordneten Element übergeben (Abb. 4.2). Die vom Server empfangenen Informationen müssen jedoch irgendwo gespeichert werden, und dann sollte eine neue Liste von Optionen in der Ansicht angezeigt werden. Wie aktualisiere ich die Ansicht, wenn die Eigenschaften nicht geändert werden können?
Eine mögliche Lösung besteht darin, jedes Mal ein Element mit neuen Eigenschaften zu rendern, wenn Sie eine neue Antwort vom Server erhalten. Aber dann müssen Sie die Logik außerhalb der Komponente platzieren - und die Komponente ist nicht mehr autark. Wenn Eigenschaftswerte nicht geändert werden können und die automatische Vervollständigung autark sein sollte, ist es offensichtlich unmöglich, Eigenschaften zu verwenden. Dann stellt sich die Frage: Wie können Ansichten als Reaktion auf Ereignisse aktualisiert werden, ohne die Komponente neu zu erstellen (createElement () oder JSX <NAME />)? Es ist dieses Problem, das Staaten lösen.
Nachdem die Antwort vom Server bereit ist, ändert der Rückrufcode den Status der Komponente entsprechend. Sie müssen diesen Code selbst schreiben. Nachdem der Status aktualisiert wurde, aktualisiert React die Ansicht automatisch für Sie (nur an den Stellen, an denen sie aktualisiert werden soll, dh an denen die Statusdaten verwendet werden).
Mit dem Status der React-Komponenten können Sie interaktive, aussagekräftige React-Anwendungen erstellen. Der Status ist ein grundlegendes Konzept, mit dem Sie React-Komponenten erstellen können, in denen Daten gespeichert und Ansichten entsprechend den Datenänderungen automatisch aktualisiert werden können.
Wie ist der Zustand der React-Komponente?
Der React-Status ist ein veränderbarer Komponentendatenspeicher - eigenständige funktionsorientierte Blöcke der Benutzeroberfläche und der Logik. "Variabilität" bedeutet, dass sich Zustandswerte ändern können. Wenn Sie den Status in der Ansicht (render ()) verwenden und die Werte später ändern, können Sie das Erscheinungsbild der Ansicht beeinflussen.
Metapher: Wenn Sie sich eine Komponente in Form einer Funktion vorstellen, auf deren Eingabe Eigenschaften und Status übertragen werden, ist das Ergebnis der Funktion eine Beschreibung der Benutzeroberfläche (Präsentation). Eigenschaften und Status erweitern Ansichten, werden jedoch für unterschiedliche Zwecke verwendet (siehe Abschnitt 4.3).
Wenn Sie mit Status arbeiten, greifen Sie über den Namen darauf zu. Der Name ist ein Attribut (dh ein Objektschlüssel oder eine Objekteigenschaft - keine Komponenteneigenschaft) dieses.state-Objekts, z. B. this.state.autocompleMatches oder this.state.inputFieldValue.
Statusdaten werden häufig verwendet, um dynamische Informationen in einer Ansicht anzuzeigen und das Rendern von Ansichten zu erweitern. Zurück zu einem früheren Beispiel eines Felds für die automatische Vervollständigung: Der Status ändert sich als Antwort auf eine XHR-Anforderung an den Server, die wiederum durch Eingabe von Daten in das Feld initiiert wird. React stellt sicher, dass Ansichten aktualisiert werden, wenn sich der in Ansichten verwendete Status ändert. Wenn sich ein Zustand ändert, ändern sich tatsächlich nur die entsprechenden Teile der Darstellungen (zu einzelnen Elementen und sogar zu den Attributwerten eines einzelnen Elements).
Alles andere im DOM bleibt unverändert. Dies ist dank des virtuellen DOM-Modells (siehe Abschnitt 1.1.1) möglich, mit dem React das Delta (Gesamtheit der Änderungen) während des Abstimmungsprozesses ermittelt. Diese Tatsache ermöglicht es Ihnen, Code in einem deklarativen Stil zu schreiben. React erledigt die ganze Routine für Sie. Die Hauptphasen zum Ändern der Präsentation werden in Kapitel 5 erläutert.
Reaktionsentwickler verwenden Status, um neue Benutzeroberflächen zu generieren. Komponenteneigenschaften (this.props), gewöhnliche Variablen (inputValue) und Klassenattribute (this.inputValue) sind hierfür nicht geeignet, da eine Änderung ihrer Werte (im Kontext der aktuellen Komponente) keine Änderung in der Ansicht auslöst. Das folgende Snippet ist beispielsweise Antipattern. Dies zeigt, dass das Ändern des Werts an einer beliebigen Stelle außer dem Status keine Aktualisierung der Ansicht bewirkt:
// : ! let inputValue = 'Texas' class Autocomplete extends React.Component { updateValues() ← { ( ) this.props.inputValue = 'California' inputValue = 'California' this.inputValue = 'California' } render() { return ( <div> {this.props.inputValue} {inputValue} {this.inputValue} </div> ) } }
Nun wollen wir sehen, wie man mit den Zuständen von React-Komponenten arbeitet.
Arbeite mit Staaten
Um mit Status zu arbeiten, müssen Sie in der Lage sein, auf Werte zuzugreifen, diese zu aktualisieren und Anfangswerte festzulegen. Beginnen wir mit dem Verweis auf Zustände in React-Komponenten.
Zugang zu Staaten
Das Statusobjekt ist ein Attribut der Komponente, und Sie sollten über diesen Link darauf zugreifen, z. B. this.state.name. Wie Sie sich erinnern, können Variablen in geschweiften Klammern ({}) auf Variablen zugegriffen und im JSX-Code angezeigt werden. In ähnlicher Weise können Sie in render () this.state (wie jedes andere Variablen- oder Klassenattribut einer nicht standardmäßigen Komponente) rendern, z. B. {this.state.inputFieldValue}. Diese Syntax ähnelt der Syntax für den Zugriff auf Eigenschaften in this.props.name.

Wir verwenden das, was Sie gelernt haben, um die Uhr in Abb. 1 zu implementieren. 4.3. Unser Ziel ist es, eine autonome Komponentenklasse zu erstellen, die jeder problemlos importieren und in seiner Anwendung verwenden kann. Die Uhr sollte die aktuelle Uhrzeit anzeigen.
Das Projekt hat folgende Struktur:
/clock index.html /jsx script.jsx clock.jsx /js script.js clock.js react.js react-dom.js
Ich verwende die Babel-CLI mit Tracking-Flags (-w) und Verzeichnis (-d), um alle JSX-Quelldateien von clock / jsx in den Zielordner clock / js zu kompilieren und neu zu kompilieren, wenn Änderungen erkannt werden. Außerdem habe ich den Befehl als npm-Skript in der Datei package.json des übergeordneten Ordners ch04 gespeichert, um den Befehl npm run build-clock von ch04 auszuführen:
"scripts": { "build-clock": "./node_modules/.bin/babel clock/jsx -d clock/js -w" },
Natürlich steht die Zeit nicht still (ob es uns gefällt oder nicht). Aus diesem Grund müssen Sie die Ansicht ständig aktualisieren und können dafür den Status verwenden. Nennen Sie es currentTime und versuchen Sie, den Status wie in Listing 4.1 gezeigt zu rendern.
Listing 4.1. JSX-Status rendern
class Clock extends React.Component { render() { return <div>{this.state.currentTime}</div> } } ReactDOM.render( <Clock />, document.getElementById('content') )
Sie erhalten eine Fehlermeldung: Uncaught TypeError: Die Eigenschaft 'currentTime' von null kann nicht gelesen werden. Normalerweise haben JavaScript-Fehlermeldungen ungefähr die gleichen Vorteile wie ein Glas kaltes Wasser für eine ertrinkende Person. Zumindest in diesem Fall zeigt JavaScript eine aussagekräftige Meldung an.
Die Nachricht zeigt an, dass der Wert von currentTime undefiniert ist. Im Gegensatz zu Eigenschaften werden Zustände nicht im übergeordneten Element festgelegt. Das Aufrufen von setState in render () schlägt ebenfalls fehl, da eine Schleife erstellt wird (setState → render → setState ...) und React einen Fehler meldet.
Zuordnung des Ausgangszustands
Sie haben bereits gesehen, dass Sie den Status initialisieren müssen, bevor Sie Statusdaten in render () verwenden. Verwenden Sie zum Festlegen des Anfangszustands this.state im Konstruktor mit der Syntax der ES6-Klasse React.Component. Denken Sie daran, super () mit Eigenschaften aufzurufen. Andernfalls funktioniert die Logik im übergeordneten Element (React.Component) nicht:
class MyFancyComponent extends React.Component { constructor(props) { super(props) this.state = {...} } render() { ... } }
Wenn Sie den Anfangszustand zuweisen, können Sie auch eine andere Logik hinzufügen. Legen Sie beispielsweise den Wert von currentTime mit new Date () fest. Sie können sogar toLocaleString () verwenden, um das richtige Datums- / Uhrzeitformat für den aktuellen Standort des Benutzers abzurufen (siehe unten (ch04 / clock)).
Listing 4.2. Taktkomponentenkonstruktor
class Clock extends React.Component { constructor(props) { super(props) this.state = {currentTime: (new Date()).toLocaleString()} } ... }
Der Wert von this.state muss ein Objekt sein. Wir werden nicht auf Details von constructor () aus ES6 eingehen. Siehe Anhang E und die ES6-Zusammenfassung unter
github.com/azat-co/cheatsheets/tree/master/es6 . Die Quintessenz ist, dass wie in anderen OOP-Sprachen ein Konstruktor (d. H. Konstruktor ()) aufgerufen wird, wenn eine Instanz der Klasse erstellt wird. Der Name der Konstruktormethode sollte genau das sein. Betrachten Sie dies als eine der Regeln von ES6. Außerdem sollte beim Erstellen der Methode constructor () fast immer der Aufruf super () enthalten sein, ohne den der übergeordnete Konstruktor nicht ausgeführt werden würde. Wenn Sie dagegen die Methode constructor () nicht definieren, wird standardmäßig der Aufruf von super () angenommen.
Der Name currentTime ist optional. Sie müssen später denselben Namen verwenden, wenn Sie diesen Status lesen und aktualisieren.
Das Statusobjekt kann verschachtelte Objekte oder Arrays enthalten. Im folgenden Beispiel wird dem Status eine Reihe von Buchbeschreibungen hinzugefügt:
class Content extends React.Component { constructor(props) { super(props) this.state = { githubName: 'azat-co', books: [ 'pro express.js', 'practical node.js', 'rapid prototyping with js' ] } } render() { ... } }
Die Methode constructor () wird nur einmal aufgerufen, wenn ein React-Element basierend auf der Klasse erstellt wird. Daher können Sie den Status mit this.state nur einmal direkt festlegen - in der Methode constructor (). Setzen oder aktualisieren Sie den Status nicht direkt mit this.state = ... an einer anderen Stelle, da dies zu unvorhergesehenen Konsequenzen führen kann.
Sie erhalten also nur den Anfangswert, der sehr schnell veraltet ist - in nur 1 Sekunde. Wer braucht eine Uhr, die nicht die aktuelle Uhrzeit anzeigt? Glücklicherweise gibt es einen Mechanismus zum Aktualisieren des aktuellen Status.
Statusaktualisierung
Der Status wird durch die Methode der Klasse this.setState (Daten, Rückruf) geändert. Wenn diese Methode aufgerufen wird, kombiniert React die Daten mit den aktuellen Status und ruft render () auf. Danach ruft es callback auf.
Das Definieren eines Rückrufs in setState () ist wichtig, da die Methode asynchron arbeitet. Wenn die Anwendung vom neuen Status abhängt, können Sie diesen Rückruf verwenden, um sicherzustellen, dass der neue Status verfügbar ist.
Wenn Sie einfach davon ausgehen, dass der Status aktualisiert wurde, ohne auf den Abschluss von setState () zu warten, dh synchron zu arbeiten, wenn eine asynchrone Operation ausgeführt wird, kann ein Fehler auftreten: Das Programm hängt von der Aktualisierung der Statuswerte ab, der Status bleibt jedoch alt.
Bisher haben wir Zeit vom Staat gerendert. Sie wissen bereits, wie Sie den Ausgangszustand einstellen, aber er sollte jede Sekunde aktualisiert werden, oder? Verwenden Sie dazu die Browser-Timer-Funktion setInterval () (http://mng.bz/P2d6), die den Status alle n Millisekunden aktualisiert. Die setInterval () -Methode ist in fast allen modernen Browsern als global implementiert, was bedeutet, dass sie ohne zusätzliche Bibliotheken oder Präfixe verwendet werden kann. Ein Beispiel:
setInterval(()=>{ console.log('Updating time...') this.setState({ currentTime: (new Date()).toLocaleString() }) }, 1000)
Um den Countdown zu starten, müssen Sie setInterval () nur einmal aufrufen. Wir erstellen die launchClock () -Methode ausschließlich zu diesem Zweck. launchClock () wird im Konstruktor aufgerufen. Die endgültige Version der Komponente ist in Listing 4.3 (ch04 / clock / jsx / clock.jsx) dargestellt.
Die setState () -Methode kann überall aufgerufen werden, nicht nur in der launchClock () -Methode (die im Konstruktor aufgerufen wird), wie im Beispiel. In der Regel wird die setState () -Methode von einem Ereignishandler oder als Rückruf aufgerufen, wenn Daten empfangen oder aktualisiert werden.
TIPP Der Versuch, den Status im Code mit einem Befehl der Form this.state.name = 'new name' zu ändern, führt zu nichts. Es wird nicht dazu führen, dass das echte DOM-Modell neu gerendert und aktualisiert wird, wie Sie es möchten. In den meisten Fällen ist eine direkte Statusänderung ohne setState () antipattern und sollte vermieden werden.
Es ist wichtig zu beachten, dass die setState () -Methode nur die Zustände aktualisiert, die an sie übergeben wurden (teilweise oder zusammengeführt, jedoch ohne vollständigen Ersatz). Es ersetzt nicht jedes Mal das gesamte Statusobjekt. Wenn sich daher nur einer der drei Zustände geändert hat, bleiben die beiden anderen unverändert. Im folgenden Beispiel ändern sich userEmail und userId nicht:
constructor(props) { super(props) this.state = { userName: 'Azat Mardan', userEmail: 'hi@azat.co', userId: 3967 } } updateValues() { this.setState({userName: 'Azat'}) }
Wenn Sie alle drei Status aktualisieren möchten, müssen Sie dies explizit tun, indem Sie die neuen Werte dieser Status an setState () übergeben. (Auch im alten Code, der jetzt nicht mehr funktioniert, wird manchmal die Methode this.replaceState () gefunden. Sie ist offiziell veraltet1. Wie Sie vielleicht beim Namen erraten haben, hat sie das gesamte Statusobjekt durch alle ihre Attribute ersetzt.)
Denken Sie daran, dass der Aufruf von setState () die Ausführung von render () initiiert. In den meisten Fällen funktioniert es. In einigen besonderen Fällen, in denen der Code von externen Daten abhängt, können Sie ein erneutes Rendern initiieren, indem Sie this.forceUpdate () aufrufen. Solche Entscheidungen sind jedoch unerwünscht, da die Komponenten aufgrund der Verwendung externer Daten (anstelle des Status) weniger zuverlässig und von externen Faktoren abhängig sind (harte Bindung).
Wie bereits erwähnt, kann auf das Statusobjekt im Eintrag this.state zugegriffen werden. In JSX werden die Ausgabewerte in geschweiften Klammern ({}) eingeschlossen. Verwenden Sie daher die Notation {this.state.NAME}, um eine Statuseigenschaft in einer Ansicht zu deklarieren (dh im Befehl return der Render-Methode).
Reaktionsmagie tritt auf, wenn Sie Statusdaten in einer Ansicht verwenden (z. B. in der Ausgabe, in einem if / else-Befehl, als Attributwert oder Eigenschaftswert eines untergeordneten Elements) und dann neue Werte für setState () übergeben. Bah! React aktualisiert alle erforderlichen HTML-Markups für Sie. Sie können dies in der DevTools-Konsole überprüfen, in der die Zyklen "Aktualisieren ..." und "Rendern ..." angezeigt werden sollen. Und das Tolle ist, dass dies nur die absolut minimal erforderlichen DOM-Elemente betrifft.
»Weitere Informationen zum Buch finden Sie auf
der Website des Herausgebers»
Inhalt»
Auszug20% Rabatt auf Gutschein für Straßenhändler -
Reagieren SieNach Zahlung der Papierversion des Buches wird eine elektronische Version des Buches per E-Mail verschickt.