Erste Schritte mit der React-JavaScript-Bibliothek
Veröffentlicht: 2022-02-16Wenn Sie Zeit in der WordPress-Welt verbringen, sind Sie wahrscheinlich auf Zac Gordon gestoßen. Zac ist ein enthusiastischer und charmanter Lehrer, der sich auf Javascript in WordPress konzentriert. Den Satz „Learn Javascript Deeply“ hat er sich von Matt Mullenweg geliehen und daraus seinen persönlichen Slogan gemacht.
In den letzten Jahren hat Zac Videokurse, Online-Konferenzen, Live-Gespräche und Podcasts produziert, die sich darauf konzentrieren, Ihnen die Verwendung von Javascript in WordPress beizubringen.
Ich freue mich, sagen zu können, dass wir mit Zac an einem Buch arbeiten, „React Explained“. React ist die Bibliothek, die das WordPress-Team für den neuen Gutenberg-Editor ausgewählt hat. Sie sind nicht allein – sowohl Drupal als auch Magento haben sich ebenfalls für React entschieden.
Zac twittert seinen Schreibfortschritt live unter @zgordon auf Twitter. Sie können Zac auch im OSTraining-Podcast über React sprechen hören.
In diesem Auszug aus dem Buch gibt Ihnen Zac einen allgemeinen Überblick über React und einige Schlüsselkonzepte.
Was ist Reagieren?
React ist standardmäßig eine Bibliothek zum Erstellen von Benutzeroberflächen.
Obwohl React eine JavaScript-Bibliothek ist, sind die von React erstellten Schnittstellen agnostisch.
Es gibt mehrere React-Begleitbibliotheken, damit die von Ihnen erstellten Schnittstellen im Browser, auf dem Server, in nativen Anwendungen und sogar in 360- und VR-Umgebungen funktionieren. In diesem Buch konzentrieren wir uns auf die Arbeit mit ReactDOM, der Bibliothek, die das Hinzufügen der Schnittstellen, die wir mit React erstellen, zu clientseitigen Websites und Anwendungen verwaltet. ReactDomServer, ReactNative und React360 sind ebenfalls Bibliotheken, die Sie möglicherweise für die Verwendung von React-Schnittstellen in anderen Umgebungen erkunden möchten.
Neben der Bereitstellung von Hilfsfunktionen zum Erstellen von Schnittstellen ermöglicht Ihnen die Architektur von React, Interaktionen mit Ihren Schnittstellen zu handhaben, unabhängig davon, ob es sich um Ereignisbehandlung, API-Aufrufe, Zustandsverwaltung, Aktualisierungen der Schnittstelle oder komplexere Interaktionen handelt.
React bietet nicht so viele Hilfsfunktionen wie einige JavaScript-Frameworks. Dies ist größtenteils der Grund, warum wir React eine Bibliothek und kein Framework nennen. Sie müssen immer noch viel Vanilla-JavaScript schreiben, wenn Sie mit React arbeiten.
Reaktionskomponentenarchitektur erklärt
Eine Komponente ist ein unabhängiges, wiederverwendbares Stück Code (erstellt über eine Funktion oder Klasse).
React verwendet eine Komponentenarchitektur zum Erstellen von Benutzeroberflächen und zum Organisieren von Code. Die Hauptdatei für eine einfache React-App könnte etwa so aussehen.
// React und andere Komponenten importieren Reagieren von 'Reagieren' importieren; importiere { render } aus 'react-dom'; Header aus './Header' importieren; MainContent aus './MainContent' importieren; Fußzeile aus './Footer' importieren; Funktion App(){ Rückkehr ( <div className="app"> <Kopfzeile /> <Hauptinhalt /> <Fußzeile /> </div> ); } ReactDOM.render( <App />, document.getElementById("root"));
Wir können hier einige Komponenten im Einsatz sehen. <Header />, <MainContent /> und <Footer /> sind alle Komponenten. Die App()-Funktion ist ebenfalls eine Komponente, und wir können in der letzten Zeile dieses Beispiels sehen, wie wir die ReactDOM-Bibliothek und die ReactDOM.render()-Methode verwenden können, um das Hinzufügen der von uns erstellten Benutzeroberfläche zu einer Webseite zu verwalten.
Wenn wir in die Komponenten <Header />, <MainContent /> und <Footer /> graben, würden wir wahrscheinlich die Verwendung von mehr Komponenten sowie etwas sehen, das wie HTML-Markup aussieht.
Reagieren von "Reagieren" importieren; Anzeige aus „../Anzeige“ importieren; Logo aus "../assets/logo.svg" importieren; Standardfunktion Header() exportieren { Rückkehr ( <header className="app-header"> <Werbung /> <img src={logo} className="app-logo" alt="logo" /> <h1 className="app-title">Site-Name</h1> </header> ); }
In dieser <Header />-Komponente oben können wir sehen, dass wir noch eine weitere Komponente namens <Ad /> einbinden. Die meisten React-Anwendungen enthalten mehrere Ebenen der Komponentenverschachtelung, wie wir bei <App />, <Header /> und <Ad /> sehen.
Wir sehen auch die Verwendung von HTML-Elementen in unserem React-Code. Dies ist dank einer Bibliothek namens JSX möglich, mit der Sie „HTML-Markup“ direkt in Ihr JavaScript schreiben können. Da wir React verwenden, um Benutzeroberflächen zu erstellen, und Benutzeroberflächen im Web HTML-Markup beinhalten, ist es sinnvoll, dass wir HTML-ähnliche Elemente in unseren UI-Komponenten sehen würden. Wir werden JSX in diesem Buch eingehend untersuchen.
Wenn wir uns einen Code für eine einfache React-App ansehen, die mit React 360, der VR-Bibliothek von React, erstellt wurde, wären die tatsächlichen Komponenten, die wir aufrufen, anders, aber die Komponentenarchitektur ist immer noch vorhanden.
Reagieren von 'Reagieren' importieren; importieren { Text, Aussicht, VrButton, } von 'reagieren-360'; Klasse Slideshow erweitert React.Component { // Code der Kürze halber entfernt Rückkehr ( <Style anzeigen={styles.wrapper}> <Style anzeigen={styles.controls}> <VrButton onClick={this.prevPhoto}> <Text>{'Vorheriger'}</Text> </VrButton> <VrButton onClick={this.nextPhoto}> <Text>{'Weiter'}</Text> </VrButton> <Ansicht> <Textstil={Stile.Titel}>{aktueller.Titel}</Text> </Ansicht> </Ansicht> ); }
Der obige Code erstellt mehrere Ebenen von 360-Grad-Ansichten mit einigen Schaltflächen und überlagertem Text. Während der eigentliche Code möglicherweise nicht ganz sinnvoll ist, sollte klar sein, dass wir mehrere verschachtelte Komponenten haben, die Ansicht, Schaltflächen und Text darstellen.
Dies ist ein gutes Beispiel, da Sie sehen können, wie dieselben Komponenten auf unterschiedliche Weise wiederverwendet werden, indem Sie ihnen unterschiedliche Parameter übergeben oder was React Props nennt. Das Verständnis, wie Daten durch React-Komponenten geleitet werden, ist wichtig, um die typische Komponentenarchitektur zu verstehen, die zum Erstellen mit React verwendet wird.
Reaktionsdatenfluss erklärt
React folgt einer Konvention zum Abrufen und Setzen von Daten am höchsten Punkt, der in einer Komponentenhierarchie erforderlich ist, damit Daten in einer Richtung nach unten durch eine Anwendung geleitet werden können. Schauen wir uns dieses Beispiel an und stellen uns einige der Datentypen vor, die wir benötigen würden für verschiedene Bauteile.
Funktion App() { Rückkehr( <Reakt.Fragment> <Kopfzeile /> <Inhalt /> <Seitenleiste /> <Fußzeile /> </React.Fragment> ); }
So etwas wie der Name der Website muss möglicherweise sowohl für <Header /> als auch für <Footer /> verfügbar sein. Der Hauptinhalt für die jeweilige Seite müsste an <Content /> übergeben werden. Einige zusätzliche Widget-Daten müssen möglicherweise zu <Sidebar /> gehen.
Funktion App() { const siteTitle = getSiteTitle(); const Widgets = getWidgets(); const mainContent = getPageContent(); Rückkehr( <Reakt.Fragment> <Header siteTitle={siteTitle} /> <Inhalt Hauptinhalt={Hauptinhalt} /> <Seitenleisten-Widgets={Widgets} /> <Footer siteTitle={siteTitle} /> </React.Fragment> ); }
Durch diese Konvention, Attributnamen zu bilden und ihnen einen Wert zuzuweisen, übergeben wir Daten an eine Komponente.
Jetzt haben <Header /> und <Footer /> Zugriff auf den Seitentitel, <Content /> hat Zugriff auf den Hauptinhalt und <Sidebar /> hat Zugriff auf die benötigten Widgets.
Ein wichtiger Hinweis ist, dass dieses Muster der Datenübergabe an eine Komponente die Daten nur um eine Ebene weiterleitet. Komponenten innerhalb von <Header /> erhalten nicht automatisch Zugriff auf siteTitle.

Funktion Header (Requisiten) { Rückkehr( <Kopfzeile> <p>Wir können den {props.siteTitle} hier sehen.</p> <PageHeader siteTitle={props.siteTitle} /> <PageSubHeader /> </header> ); }
Sie können hier sehen, dass wir innerhalb von <Header /> props.siteTitle aufrufen können und Zugriff auf den Wert haben, den wir ihm übergeben haben. Wenn wir jedoch Zugriff auf siteTitle innerhalb der <PageHeader />-Komponente haben wollten, müssten wir diese Informationen ebenfalls manuell weitergeben.
Wenn eine Komponente einen Wert als Prop erhält, sollte sie ihn nicht ändern. Requisiten sollten als unveränderliche Daten einen Komponentenbaum durchlaufen. Dadurch wird sichergestellt, dass jede Komponente, die auf eine Requisite verweist, auf denselben Wert verweist wie ihre übergeordnete oder untergeordnete Komponente.
Der Wert einer Stütze sollte nur in der Komponente geändert werden, die ursprünglich den Wert der Stütze festgelegt und damit begonnen hat, ihn nach unten durch den Komponentenbaum zu leiten. In unserem obigen Beispielcode könnte die Komponente <App /> den Wert von siteTitle ändern, die Komponenten <Header /> oder <PageHeader /> sollten dies jedoch nicht.
Um zu verstehen, wie dynamische Daten in einer React-App aktualisiert werden, müssen der Zustand und die Übergabe von Ereignishandlern als Requisiten diskutiert werden.
Zustände der Reaktionskomponenten erklärt
Wie wir gelernt haben, fließen Daten unverändert durch Komponenten als Requisiten. Die Daten werden an der höchsten Komponente im Baum gesetzt, die für alle untergeordneten Komponenten erforderlich ist, um die Informationen zu übergeben, die als Requisiten benötigt werden.
In einigen Fällen werden diese Daten einmal empfangen und müssen nicht geändert werden. In vielen Fällen müssen diese Daten jedoch dynamisch bleiben und jederzeit aktualisiert werden können, sodass sich diese Aktualisierung in allen untergeordneten Komponenten widerspiegelt.
Um Daten zu verfolgen, die sich in React ändern, haben wir ein React-Zustandsobjekt und eine Reihe von Hilfsfunktionen, um den Zustandswert zu aktualisieren.
Hier ist ein Beispiel für einen Zähler, der sich selbst aktualisiert. Der Wert des Zählers ist ein Wert, der innerhalb dieser Komponente dynamisch ist und daher ein gutes Beispiel dafür ist, wann man sich auf den Zustand verlassen sollte. Beachten Sie, dass wir zum Erstellen von Komponenten mit Status JavaScript-Klassen anstelle von Funktionen verwenden müssen.
Klasse Counter erweitert Komponente { Zustand = { Zähler: 0 }; handleCount = () => { this.setState({ Zähler: this.state.counter + 1 }); }; rendern() { Rückkehr ( <div> <h1>{dieser.zustand.zähler}</h1> <button onClick={this.handleCount}>Aufwärts zählen!!</button> </div> ); } }
Nun ist es wichtig zu beachten, dass dieser Zustand nur auf diese Komponente beschränkt ist. Der Wert von state in counter wäre für untergeordnete oder übergeordnete Komponenten nicht verfügbar.
In einem komplexeren Beispiel wie unten müssten wir also den Wert von counter down als Stütze an das untergeordnete Element übergeben.
Klasse Counter erweitert Komponente { Zustand = { zählen: 0 }; handleCount = () => { this.setState({ Anzahl: this.state.count + 1 }); }; rendern() { Rückkehr ( <div> <PageHeader count={this.state.count} /> <button onClick={this.handleCount}>Aufwärts zählen!!</button> </div> ); } }
Die Stütze <PageHeader /> count wird jedes Mal aktualisiert, wenn wir den Status in der Komponente <Counter /> aktualisieren
Funktion Seitenkopf (Requisiten) { <h1>{props.count}</h1> zurückgeben; }
Das Schöne an diesem Ansatz ist, dass jedes Mal, wenn der Status aktualisiert wird, automatisch ein neuer Wert an alle untergeordneten Komponenten weitergegeben wird, wobei der Wert einer Requisite auf State gesetzt wird.
Dadurch haben wir einen Single Point of Truth für dynamische Daten. Die Quelle der Wahrheit ist der Zustandswert, verwaltet von einer einzigen Komponente. Alle Instanzen dieses Werts in untergeordneten Komponenten sind unveränderliche Werte, die als Requisiten empfangen werden und außerhalb dieser Komponente nicht geändert werden sollten.
Komponenten, die in der Hierarchie über dieser Komponente erscheinen, hätten keinen Zugriff auf diese Daten, da sie nur über Requisiten nach unten weitergegeben werden. Wir sehen erneut, warum wir versuchen, den Zustand von Komponenten höher in der Hierarchie festzulegen und zu verwalten, damit die Daten für alles verfügbar sind, was sie benötigt.
Es gibt einige andere Architekturmuster, wie Komponenten höherer Ordnung und die Kontext-API, die die Notwendigkeit umgehen, Tonnen von Requisiten manuell durch Ihre App zu übergeben. Wir werden diese später genauer untersuchen. Fürs Erste wollen wir sicherstellen, dass wir diesen groben Überblick darüber verstehen, wie die Dinge im Allgemeinen funktionieren, bevor wir anfangen, Abkürzungen zu nehmen.
Aktualisieren von Komponentenzuständen in React
Was passiert nun, wenn wir auslösen möchten, dass der Status von einer untergeordneten Komponente aktualisiert wird?
Stellen Sie sich zum Beispiel vor, dass wir mit dem obigen Beispiel eine <Button />-Komponente anstelle einer fest codierten Schaltfläche in unserer Hauptkomponente <Counter /> haben wollten? Das ist bei komplexen Apps eigentlich recht üblich.
Die Lösung dafür besteht in der React-Welt darin, die Event-Handler-Funktion zu übergeben, die den Status mit setState als Prop aktualisiert. Dann kann es von jeder untergeordneten Komponente aufgerufen werden, aber die Aktion findet in der ursprünglichen Komponente statt, die den Status festgelegt hat, und kann ihn auch aktualisieren. Es gibt andere Muster dafür, aber dieser Ansatz ist der grundlegendste.
Wenn Sie mit der Übergabe von Funktionen als Parameter nicht vertraut sind, handelt es sich um vollständig gültiges Vanilla-JavaScript.
Sobald der Status aktualisiert ist, wird er über die Requisiten durch die Komponentenhierarchie nach unten weitergegeben.
Hier ist ein Beispiel, wie das aussehen würde.
Klasse Counter erweitert Komponente { Zustand = { zählen: 0 }; handleCount = () => { this.setState({ Anzahl: this.state.count + 1 }); }; rendern() { Rückkehr ( <div> <PageHeader count={this.state.count} /> <Schaltfläche handleCount={this.handleCount} /> </div> ); } } Funktion Seitenkopf ( Requisiten ) { Rückkehr( <h1>{props.count}</h1> ); } Funktionstaste ( Requisiten ) { Rückkehr( <button onClick={props.handleCount}>Aufwärts zählen!!</button> ); }
Hier sehen wir ein einfaches Beispiel dafür, wie React den Datenfluss handhabt. Es gibt einen Single Point of Truth für Daten. Das existiert im Statussatz und wird von einer einzigen Komponente aktualisiert. Daten werden in einem Einwegfluss nach unten durch einen verschachtelten Komponentenbaum über Requisiten geleitet.
Wenn der Zustand von einer anderen Komponente als der ursprünglich festgelegten aktualisiert werden muss, kann ein Ereignishandler als Prop an die erforderliche untergeordnete Komponente weitergegeben werden. Dadurch bleiben die Daten unveränderlich und fließen in eine Richtung, denn selbst wenn eine untergeordnete Komponente eine Änderung auslöst, findet diese Änderung weiter oben in der ursprünglichen Komponente statt.
Wenn wir den Wert einer Requisite etwas aus dem Zustand zuweisen, wie unten, wird dieser Requisitenwert automatisch aktualisiert, wenn sich der Zustand ändert.
<PageHeader-Zähler={this.state.count} />
Alle anderen untergeordneten Komponenten, die auf diesen Prop-Wert verweisen, erhalten das Update ebenfalls automatisch. Das ist das Schöne am Datenfluss in React.
Dies kann eine Weile dauern, bis Sie sich daran gewöhnt haben, je nachdem, wie Sie solche Probleme mit JavaScript in der Vergangenheit angegangen sind. All dies sollte uns jedoch als guter Ausgangspunkt dienen, um uns eingehender mit der Erklärung von React befassen zu können.