
Wenn Sie Twitter lesen, wissen Sie höchstwahrscheinlich, dass Hooks eine neue React-Funktion ist, aber Sie fragen sich vielleicht,
wie wir sie in der Praxis einsetzen können . In diesem Artikel zeigen wir Ihnen einige Beispiele für die Verwendung von Hooks.
Eine der wichtigsten Ideen, die Sie verstehen sollten, ist,
dass Sie mit Hooks Status- und andere React-Funktionen verwenden können, ohne Klassen schreiben zu müssen .
Die Motivation hinter den Haken
Obwohl die komponentenorientierte Architektur es uns ermöglicht, die Ansicht in unserer Anwendung wiederzuverwenden, besteht eines der größten Probleme für Entwickler darin, die
zustandsbasierte Logik zwischen Komponenten wiederzuverwenden . Wenn wir Komponenten mit ähnlicher Zustandslogik haben, gibt es keine guten Lösungen für die Wiederverwendung von Komponenten, und dies kann manchmal zu einer Verdoppelung der Logik in den Konstruktor- und Lebenszyklusmethoden führen.
Verwenden Sie normalerweise Folgendes, um dieses Problem zu lösen:
- Komponenten hoher Ordnung
- Requisiten rendern
Beide Muster weisen jedoch Nachteile auf, die zur Komplexität der Codebasis beitragen können.
Hooks zielen darauf ab, all diese Probleme zu lösen, sodass Sie Funktionskomponenten schreiben können, die Zugriff auf Status, Kontext, Lebenszyklusmethoden, Ref usw. haben, ohne Klassen schreiben zu müssen.Haken in Alpha
Bevor wir tauchen, ist es wichtig zu erwähnen, dass die Entwicklung der Hooks-API noch nicht abgeschlossen ist.
Darüber hinaus ist die offizielle Dokumentation sehr gut, und wir empfehlen, sie auch zu lesen, da sie die Motivation für die Einführung von Hooks ausführlich beschreibt.
UPD Der Originalartikel, dessen Übersetzung Sie gerade lesen, wurde zu einem Zeitpunkt geschrieben, als sich diese API im Alpha-Test befand. Derzeit ist React Hooks offiziell einsatzbereit. Irreversible Änderungen an der Version (im Vergleich zu Alpha) finden Sie am Ende des Artikels oder in den Versionshinweisen .
Wie hängen Haken mit Klassen zusammen?
Wenn Sie mit React vertraut sind, können Sie Hooks am besten verstehen, indem Sie sehen, wie wir das Verhalten reproduzieren können, mit dem wir bei der Verwendung von Klassen mit Hooks gewohnt sind.
Denken Sie daran, dass wir beim Schreiben von Komponentenklassen häufig Folgendes tun müssen:
- Status verwalten
- Verwenden Sie Lebenszyklusmethoden wie componentDidMount () und componentDidUpdate ()
- Zugriffskontext (statischer Kontexttyp)
Mit React Hooks können wir ein ähnliches Verhalten in Funktionskomponenten reproduzieren:
- Um den Status einer Komponente zu verwenden, verwenden Sie den Hook useState ()
- Verwenden Sie anstelle von Lifecycle-Methoden wie componentDidMount () und componentDidUpdate () den Hook useEffect ().
- Verwenden Sie anstelle der statischen Eigenschaft contextType den Hook useContext ().
Für die Verwendung von Hooks ist die neueste Version von React erforderlich.
Sie können sofort mit Hooks beginnen, indem Sie den Wert von react und react-dom in Ihrer package.json auf "next" ändern.

UseState () Hook-Beispiel
Der Zustand ist ein wesentlicher Bestandteil von React. Es ermöglicht uns, Variablen zu deklarieren, die Daten enthalten, die wiederum in unserer Anwendung verwendet werden. Bei Verwendung von Klassen wird der Status normalerweise wie folgt definiert:

Vor Hooks wurde state normalerweise nur in einer Komponente verwendet - einer Klasse, aber wie oben erwähnt,
können wir mit Hooks auch einer funktionalen Komponente state hinzufügen .
Sehen wir uns unten ein Beispiel an. Hier bauen wir einen Schalter mit Hintergrundbeleuchtung, der je nach Statuswert seine Farbe ändert. Dafür verwenden wir hook useState ().
Hier ist der vollständige Code (und ein ausführbares Beispiel) - wir werden uns ansehen, was unten passiert. Durch Klicken auf das Bild können Sie dieses Beispiel in CodeSandBox anzeigen.

Unsere Komponente ist eine Funktion
Im obigen Codeblock importieren wir zunächst
useState aus React. UseState ist eine neue Möglichkeit, die Möglichkeiten zu nutzen, die this.state bieten könnte.
Beachten Sie dann, dass diese Komponente
eine Funktion und keine Klasse ist . Interessant!
Lese- und Schreibzustand
Innerhalb dieser Funktion rufen wir useState auf, um eine Variable im Status zu erstellen:
useState wird zum Deklarieren einer Statusvariablen verwendet und kann mit jedem
Werttyp initialisiert werden (im Gegensatz zum Status in Klassen, der ein Objekt sein sollte).
Wie oben gezeigt, verwenden wir die Destrukturierung für den Rückgabewert von useState.
- Der erste Wert, in diesem Fall hell, ist der aktuelle Status (wie this.state).
- Der zweite Wert ist die Funktion zum Aktualisieren des Statuswerts (erster Wert) (wie this.setState).
Dann erstellen wir zwei Funktionen, von denen jede den Status auf unterschiedliche Werte setzt, 0 oder 1.

Dann wenden wir sie als Ereignishandler auf Schaltflächen in der Ansicht an:

Spurstatus reagieren
Wenn die Taste „On“ gedrückt wird, wird die Funktion setOn aufgerufen, die setLight (1) aufruft. Durch Aufrufen von setLight (1) wird
der Lichtwert für das nächste Rendern aktualisiert . Dies mag ein wenig magisch erscheinen, aber
React verfolgt den Wert dieser Variablen und übergibt einen neuen Wert, wenn diese Komponente gerendert wird.
Dann verwenden wir den aktuellen Zustand (
Licht ), um zu bestimmen, ob die Lampe eingeschaltet sein soll oder nicht. Das heißt, wir stellen die Füllfarbe des SVG in Abhängigkeit vom
Lichtwert ein . Wenn das Licht 0 (aus) ist, wird fillColor auf # 000000 gesetzt (und wenn es 1 (ein) ist, wird fillColor auf # ffbb73 gesetzt).
Mehrere Zustände
Obwohl wir dies im obigen Beispiel nicht tun, können Sie mehrere Status erstellen, indem Sie useState mehrmals aufrufen. Zum Beispiel:

HINWEIS
Es gibt einige Einschränkungen bei der Verwendung von Hooks, die Sie beachten sollten. Am wichtigsten ist, dass Sie Hooks nur auf der obersten Ebene Ihrer Funktion aufrufen. Weitere Informationen finden Sie unter „ Hooks-Regeln “.
Beispiel für einen UseEffect () - Hook
Mit UseEffect Hook können Sie Nebenwirkungen in Funktionskomponenten ausführen . Zu den Nebenwirkungen können der Zugriff auf die API, das Aktualisieren des DOM und das Abonnieren von Ereignishandlern gehören. Sie möchten lediglich, dass eine „zwingende“ Aktion ausgeführt wird.
Mit dem useEffect () - Hook weiß React, dass Sie nach dem Rendern eine bestimmte Aktion ausführen möchten.
Schauen wir uns unten ein Beispiel an. Wir werden useEffect () verwenden, um die API aufzurufen und eine Antwort zu erhalten.

In diesem Codebeispiel werden sowohl
useState als auch
useEffect verwendet . Dies liegt daran, dass das Ergebnis des API-Aufrufs in state geschrieben werden soll.

Daten empfangen und Status aktualisieren
Um den Effekt zu verwenden, müssen wir unsere Aktion in die Funktion
useEffect einfügen ,
dh wir übergeben den Effekt „action“ als anonyme Funktion als erstes Argument für
useEffect .
Im obigen Beispiel verweisen wir auf eine API, die eine Liste von Namen zurückgibt. Wenn die
Antwort zurückkehrt, konvertieren wir sie in JSON und setzen dann
setNames (Daten) , um den Status
festzulegen .

Leistungsprobleme bei der Verwendung von Effekten
Es gibt jedoch noch etwas zu sagen über die Verwendung von
useEffect .
Das erste,
woran Sie denken sollten, ist, dass unser
useEffect standardmäßig bei jedem Rendern aufgerufen wird! Die gute Nachricht ist, dass wir uns keine Gedanken über veraltete Daten machen müssen, aber die schlechte Nachricht ist, dass wir wahrscheinlich nicht für jedes Rendering eine HTTP-Anfrage stellen möchten (wie in diesem Fall).
Sie können Effekte wie in diesem Fall
mit dem zweiten Argument useEffect überspringen. Das zweite Argument für useEffect ist eine Liste von Variablen, die wir „beobachten“ möchten. Anschließend wird der Effekt nur dann erneut ausgeführt, wenn sich einer dieser Werte ändert.
Beachten Sie im obigen Codebeispiel, dass wir als zweites Argument
ein leeres Array übergeben . Wir sagen React, dass wir diesen Effekt nur beim Mounten der Komponente benennen möchten.
Weitere Informationen zur Effektleistung finden Sie in diesem Abschnitt in White Papers.
Darüber hinaus können Sie mit useEffect wie mit der useState-Funktion mehrere Instanzen verwenden, was bedeutet, dass Sie mehrere useEffect-Funktionen haben können.
Beispiel für einen UseContext () - Hook
KontextpunktDer Kontext in React ist eine Möglichkeit für eine untergeordnete Komponente, auf einen Wert in der übergeordneten Komponente zuzugreifen.
Um die Notwendigkeit des Kontexts zu verstehen: Beim Erstellen einer React-Anwendung müssen Sie häufig Werte von oben in Ihrem React-Baum nach unten übergeben. Wenn Sie keinen Kontext verwenden, leiten Sie Requisiten durch Komponenten, die nichts über sie wissen müssen.
Das Weitergeben von Requisiten über den Baum „nicht verwandter“ Komponenten wird liebevoll als Requisitenbohren bezeichnet.
React Context löst das Problem beim Bohren von Requisiten, indem Sie Werte über den Komponentenbaum mit jeder Komponente teilen können, die diese Werte anfordert.
useContext () vereinfacht die Verwendung von KontextMit useContext Hook ist die Verwendung von Kontext einfacher als je zuvor.
Die Funktion
useContext () verwendet ein
Kontextobjekt , das zunächst von
React.createContext () zurückgegeben wird , und gibt dann den aktuellen Kontextwert zurück. Schauen wir uns unten ein Beispiel an.

Im obigen Code wird der Kontext des JediContext mit React.createContext () erstellt.
Wir verwenden JediContext.Provider in unserer App-Komponente und setzen dort den Wert auf "Luke". Dies bedeutet, dass jede Komponente, die auf den Kontext zugreifen muss, diesen Wert jetzt lesen kann.
Um diesen Wert in der Funktion Display () zu lesen, rufen wir useContext auf und übergeben das JediContext-Argument.
Dann übergeben wir das Kontextobjekt, das wir von React.createContext erhalten haben, und es zeigt automatisch den Wert an. Wenn der Providerwert aktualisiert wird, arbeitet dieser Hook automatisch mit dem letzten Kontextwert.
Abrufen eines Links zum Kontext in einer größeren Anwendung
Oben haben wir JediContext in beiden Komponenten erstellt, aber in einer größeren Anwendung befinden sich Display und App in unterschiedlichen Dateien. Wenn Sie eine ähnliche Situation haben, fragen Sie sich möglicherweise: "Wie erhalten wir einen Link zu JediContext zwischen Dateien?"
Die Antwort ist, dass Sie
eine neue Datei erstellen müssen
, die den JediContext exportiert .
Beispielsweise könnten Sie eine Datei context.js haben, die Folgendes enthält:

und dann sollten Sie in App.js (und Display.js) schreiben:

Danke,
Dave )
UseRef () Hook-Beispiel
Refs bietet eine Möglichkeit, auf React-Elemente zuzugreifen, die mit der render () -Methode erstellt wurden.
Wenn Sie mit React-Refs noch nicht vertraut sind, können Sie diese
Einführung zu React-Refs lesen.
Die Funktion
useRef () gibt ein ref-Objekt zurück.

useRef () und Formulare mit Eingabe
Sehen wir uns ein Beispiel mit dem Hook useRef () an.

Im obigen Beispiel verwenden wir useRef () in Kombination mit useState (), um den Eingabewert für das p-Tag zu rendern.
Ref wird in der Variablen nameRef erstellt. Dann kann die Variable nameRef in der Eingabe verwendet werden, angegeben als ref. Im Wesentlichen bedeutet dies, dass nun der Inhalt des Eingabefeldes über ref zugänglich ist.
Die Senden-Schaltfläche im Code verfügt über einen onClick-Ereignishandler namens submitButton. Die Funktion submitButton ruft setName auf (erstellt über useState).
Wie bereits bei hookState wird setName verwendet, um den Statusnamen festzulegen. Um den Namen aus dem Eingabe-Tag zu extrahieren, lesen wir den Wert von nameRef.current.value.
Ein weiterer Hinweis zu useRef ist, dass es mehr als das ref-Attribut verwendet werden kann.
Benutzerdefinierte Hooks verwenden
Eine der coolsten Funktionen von Hooks ist, dass Sie die
Logik problemlos
zwischen mehreren Komponenten austauschen können, indem Sie Ihren eigenen Hook erstellen.Im folgenden Beispiel erstellen wir einen benutzerdefinierten
setCounter () - Hook, mit dem wir den Status verfolgen und benutzerdefinierte
Statusaktualisierungsfunktionen bereitstellen können!
Siehe auch diesen useCounter Hook von React -Use und useCounter von Kent

Im obigen Codeblock erstellen wir eine useCounter-Funktion, die die Logik unseres Hooks speichert.
Bitte beachten Sie, dass useCounter möglicherweise andere Hooks verwendet! Beginnen wir mit der Erstellung eines neuen Hook-Status über useState.
Dann definieren wir zwei
Hilfsfunktionen :
Inkrementieren und
Dekrementieren , die
setCount aufrufen und die aktuelle
Anzahl entsprechend anpassen.
Schließlich geben wir die Links zurück, die für die Interaktion mit unserem Hook erforderlich sind.
F: Was passiert, wenn ein Array mit einem Objekt zurückgegeben wird?
A: Nun, wie die meisten Dinge in Hooks sind die API-Konventionen noch nicht vollständig. Aber was wir hier tun, gibt ein Array zurück, wobei:
- Das erste Element ist der aktuelle Wert des Hakens.
- Das zweite Element ist ein Objekt, das die Funktionen enthält, die zur Interaktion mit dem Hook verwendet werden.
Mit dieser Konvention können Sie den aktuellen Wert des Hooks einfach „umbenennen“ - wie oben bei
myCount .
Sie können jedoch alles, was Sie möchten, von Ihrem benutzerdefinierten Hook zurückgeben.
Im obigen Beispiel verwenden wir in unserer Ansicht
Inkremente und
Dekremente als
onClick- Handler. Wenn der Benutzer die Tasten drückt, wird der Zähler aktualisiert und in der Ansicht erneut angezeigt (wie bei
myCount ).
Schreiben von Tests für React Hooks
Um Tests für Hooks zu schreiben, verwenden wir die
React-Testing-Bibliothek zum Testen.
Die React
-Testing-Bibliothek ist eine sehr leichte Lösung zum Testen von React-Komponenten. Es ist eine Erweiterung von
React-Dom und
React-Dom / Test-Utils . Durch die Verwendung der
React-Testing-Bibliothek wird sichergestellt, dass Ihre Tests direkt mit DOM-Knoten funktionieren.
Bei Testhaken ist noch nicht alles klar. Derzeit können Sie den Hook nicht isoliert testen. Stattdessen müssen Sie Ihren Haken an der Komponente befestigen und diese Komponente testen.
Im Folgenden werden wir Tests für unsere Hooks schreiben, die mit unseren Komponenten interagieren und nicht direkt mit Hooks. Die gute Nachricht ist, dass unsere Tests wie normale Reaktionstests aussehen werden.
Testen des useState () - Hooks
Sehen wir uns ein Beispiel für das Schreiben von Tests für
useState Hook an. Im obigen Tutorial testen wir weitere Variationen des oben verwendeten useState-Beispiels. Wir werden Tests schreiben, um sicherzustellen, dass durch Drücken der Taste „Aus“ der Status auf 0 und durch Drücken der Taste „Ein“ der Status auf 1 gesetzt wird.

Im obigen Codeblock importieren wir zunächst einige Helfer aus der
React-Testing-Bibliothek und der zu
testenden Komponente.
- Rendern , dies hilft bei der Anzeige unserer Komponente. Es wird in einen Container gerendert, der zu document.body hinzugefügt wird
- getByTestId ruft das DOM-Element von data-testid ab
- Mit fireEvent werden DOM-Ereignisse "ausgelöst". Es wird ein Ereignishandler angehängt, um beispielsweise einige DOM-Ereignisse durch Ereignisdelegierung zu dokumentieren und zu verarbeiten. durch Klicken auf eine Schaltfläche.
Außerdem legen wir in der
Testgenehmigungsfunktion die Werte von Variablen für Elemente mit
data-testid und deren Werte fest, die wir im Test verwenden möchten. Mit Links zu Elementen im DOM können wir dann die
fireEvent- Methode verwenden, um einen Klick auf eine Schaltfläche zu simulieren.
Der Test überprüft, ob beim Klicken auf
onButton der Statuswert auf 1 gesetzt ist und wenn Sie auf
offButton klicken, der
Status 1 ist.
Testen von useEffect () Hook
In diesem Beispiel schreiben wir Tests, um mit
useEffect Hook ein Produkt in den Warenkorb zu
legen . Die Anzahl der Elemente wird auch in localStorage gespeichert. Die Datei index.js in CodeSandbox enthält die eigentliche Logik zum Hinzufügen von Artikeln zum Warenkorb.
Wir werden Tests schreiben, um sicherzustellen, dass die Aktualisierung der Anzahl der Warenkorbartikel auch in localStorage angezeigt wird. Selbst wenn die Seite neu geladen wird, bleibt die Anzahl der Warenkorbartikel gleich.

In der Funktion, die den Test bestätigt, setzen wir
cartItem in
localStorage zuerst auf 0, was bedeutet, dass die Anzahl der Warenkorbelemente 0 beträgt. Dann erhalten wir durch Destrukturierung sowohl
Container als auch
Renderer von der
App- Komponente.
Durch erneutes Rendern können wir das
Neuladen von Seiten simulieren.
Dann erhalten wir die Links zu den Schaltflächen und dem p-Tag, das den aktuellen Warenkorbwert anzeigt und sie auf Variablen setzt.
Sobald dies erledigt ist, simuliert der Test einen Klick auf
addButton und prüft, ob der aktuelle Warenkorbzähler 1 ist, und lädt die Seite neu. Wenn dann geprüft wird, ob
localStorage , wird
cartItem auf 1 gesetzt. Dann simuliert er einen Klick auf
resetButton und prüft, ob die aktuelle Anzahl der Warenkorbartikel auf 0 gesetzt ist.
Testen von useRef () Hook
In diesem Beispiel werden wir
useRef Hook testen und das ursprüngliche
useRef- Beispiel oben als Grundlage für den Test verwenden.
UseRef wird verwendet, um den Wert aus dem Eingabefeld
abzurufen und den Wert dann auf state zu setzen. Die Datei
index.js in
CodeSandbox enthält die Logik zum Eingeben und Senden eines Werts.

In der Funktion, die den Test genehmigt, setzen wir die Variablen im Eingabefeld, ein p-Tag, das den aktuellen Wert von ref anzeigt, und eine Senden-Schaltfläche. Wir legen auch den Wert fest, den wir in das Eingabefeld für die Variable newName eingeben möchten. Dies wird zur Überprüfung im Test verwendet.

Die fireEvent.change-Methode wird verwendet, um einen Wert in das Eingabefeld einzugeben. In diesem Fall wird der in der Konstante newName gespeicherte Name verwendet, wonach die Senden-Schaltfläche gedrückt wird.
Der Test prüft dann, ob der
Referenzwert nach dem Drücken der Taste
mit dem Wert von
newName übereinstimmt .
Schließlich sollten Sie sehen "Keine Testabstürze, Glückwunsch!" Nachricht in der Konsole.
Community-Antwort auf Hooks
Seit der Einführung von React Hooks war die Community von dieser Funktion begeistert, und wir haben
viele Beispiele und Beispiele für die Verwendung von React Hooks gesehen. Hier sind einige der wichtigsten:
- Diese Seite enthält eine Sammlung von React Hooks.
- React -Use , die Bibliothek, die mit einer Reihe von React Hooks geliefert wird.
- Dieses CodeSandbox- Beispiel zeigt, wie Sie mit useEffect Hook Animationen mit React -Spring erstellen
- Ein useMutableReducer- Beispiel , mit dem Sie einfach einen Status mutieren können, um ihn in einem Reduzierer zu aktualisieren.
- Dieses Beispiel befindet sich in CodeSandbox, das eine komplexe integrierte Verwendung der Eltern-Kind-Kommunikation und die Verwendung von Redisern zeigt.
- React Hooks Switch-Komponente
- Eine weitere Sammlung von React Hooks mit Hooks für Eingabewerte, Geräteorientierung und Dokumentensichtbarkeit.
Verschiedene Arten von Haken
Es gibt verschiedene Arten von Hooks, die Sie in Ihrer React-Anwendung verwenden können. Sie sind unten aufgeführt:
- useState - ermöglicht es uns, reine Funktionen mit Zugriff auf den Status darin zu schreiben.
- useEffect - ermöglicht es uns, Nebenwirkungen durchzuführen. Nebenwirkungen können API-Aufrufe, das Aktualisieren des DOM und das Abonnieren von Ereignishandlern sein.
- useContext - Ermöglicht das Schreiben reiner Funktionen mit Kontext.
- useReducer - gibt uns einen Link zu einem Redux-ähnlichen Reduzierer
- useRef - Ermöglicht das Schreiben reiner Funktionen, die ein veränderbares Referenzobjekt zurückgeben.
- useMemo - .
- useCallback — Hook .
- useImperativeMethods - , ref.
- useMutationEffects — useEffect Hook , DOM-.
- useLayoutEffect - DOM -.
- hooks - .
hooks
Das Tolle an Hooks ist, dass sie neben dem vorhandenen Code arbeiten, sodass Sie langsam Änderungen vornehmen können, die Hooks implementieren. Sie müssen lediglich ein Upgrade durchführen. Reagieren Sie auf eine Version, die Hooks unterstützt.Die Hooks sind jedoch immer noch eine experimentelle Funktion, und das React-Team hat wiederholt gewarnt, dass sich die API ändern kann. Bedenken Sie, dass Sie gewarnt werden.Was bedeutet das Aufkommen von Haken für den Unterricht? Wie das React-Team berichtet, bleiben die Klassen weiterhin bestehen, sie sind ein großer Teil der React-Codebasis und werden höchstwahrscheinlich noch einige Zeit dauern.. Facebook , , , , . React Hooks, —
API- Hooks , Hooks, , .Zusätzliche Ressourcen
- React React Hooks,
- API .
- RFC, ,
UPD
:
React 16.8 Hooks API. -:
— useMutationEffect.
— useImperativeMethods useImperativeHandle.
— useState useReducer Hooks.
— , useEffect/useMemo/useCallback Hooks.
— Object.is useState useReducer.
— Strict Mode (DEV-only).
— lazy initialization API useReducer Hook.
.