Auf Eingaben mit State reagieren
React bietet eine deklarative Möglichkeit, die Benutzeroberfläche zu manipulieren. Anstatt einzelne Teile der Benutzeroberfläche direkt zu manipulieren, beschreibst du die verschiedenen Zustände, in denen sich deine Komponente befinden kann, und wechselst zwischen ihnen als Reaktion auf Benutzereingaben. Dies ähnelt der Denkweise von Designern über die Benutzeroberfläche.
Sie werden lernen
- Wie sich deklarative UI-Programmierung von imperativer UI-Programmierung unterscheidet
- Wie du die verschiedenen visuellen Zustände auflistest, in denen sich deine Komponente befinden kann
- Wie du die Änderungen zwischen den verschiedenen visuellen Zuständen aus dem Code auslöst
Wie sich deklarative UI mit imperativer vergleicht
Wenn du UI-Interaktionen entwirfst, denkst du wahrscheinlich darüber nach, wie sich die Benutzeroberflächeverändertals Reaktion auf Benutzeraktionen. Betrachte ein Formular, das dem Benutzer das Absenden einer Antwort ermöglicht:
- Wenn du etwas in das Formular eingibst, wird der „Absenden“-Buttonaktiviert.
- Wenn du auf „Absenden“ drückst, werden sowohl das Formular als auch der Buttondeaktiviert,und ein Ladeindikatorerscheint.
- Wenn die Netzwerkanfrage erfolgreich ist, wird das Formularausgeblendet,und die „Danke“-Nachrichterscheint.
- Wenn die Netzwerkanfrage fehlschlägt, erscheint eine Fehlermeldung,und das Formular wirdwieder aktiviert.
Bei derimperativen Programmierungentspricht das oben Gesagte direkt der Art und Weise, wie du Interaktionen implementierst. Du musst die genauen Anweisungen schreiben, um die Benutzeroberfläche je nach dem, was gerade passiert ist, zu manipulieren. Hier ist eine andere Denkweise: Stell dir vor, du sitzt neben jemandem im Auto und sagst ihm Kurve für Kurve, wohin er fahren soll.

Illustriert vonRachel Lee Nabors
Sie wissen nicht, wohin du willst, sie folgen nur deinen Befehlen. (Und wenn du die Wegbeschreibung falsch angibst, landest du am falschen Ort!) Es wirdimperativgenannt, weil du jedes Element, vom Ladeindikator bis zum Button, „befehlen“ musst, indem du dem Computer sagst,wieer die Benutzeroberfläche aktualisieren soll.
In diesem Beispiel für imperative UI-Programmierung wird das FormularohneReact erstellt. Es verwendet nur dasDOMdes Browsers:
Die imperative Manipulation der Benutzeroberfläche funktioniert für isolierte Beispiele gut genug, wird aber in komplexeren Systemen exponentiell schwieriger zu handhaben. Stellen Sie sich vor, Sie müssten eine Seite voller verschiedener Formulare wie dieses aktualisieren. Das Hinzufügen eines neuen UI-Elements oder einer neuen Interaktion würde eine sorgfältige Überprüfung des gesamten bestehenden Codes erfordern, um sicherzustellen, dass Sie keinen Fehler eingeführt haben (z. B. etwas zu vergessen, anzuzeigen oder auszublenden).
React wurde entwickelt, um dieses Problem zu lösen.
In React manipulieren Sie die Benutzeroberfläche nicht direkt – das heißt, Sie aktivieren, deaktivieren, zeigen oder verbergen Komponenten nicht direkt. Stattdessendeklarieren Sie, was Sie anzeigen möchten,und React ermittelt, wie die Benutzeroberfläche aktualisiert werden muss. Stellen Sie sich vor, Sie steigen in ein Taxi und sagen dem Fahrer, wohin Sie möchten, anstatt ihm genau zu sagen, wo er abbiegen soll. Es ist die Aufgabe des Fahrers, Sie dorthin zu bringen, und er kennt vielleicht sogar einige Abkürzungen, an die Sie nicht gedacht haben!

Illustriert vonRachel Lee Nabors
Über die Benutzeroberfläche deklarativ nachdenken
Sie haben oben gesehen, wie man ein Formular imperativ implementiert. Um besser zu verstehen, wie man in React denkt, werden Sie im Folgenden die Neugestaltung dieser Benutzeroberfläche in React durchgehen:
- IdentifizierenSie die verschiedenen visuellen Zustände Ihrer Komponente
- BestimmenSie, was diese Zustandsänderungen auslöst
- RepräsentierenSie den Zustand im Speicher mit
useState - EntfernenSie alle nicht wesentlichen Zustandsvariablen
- VerbindenSie die Event-Handler, um den Zustand zu setzen
Schritt 1: Identifizieren Sie die verschiedenen visuellen Zustände Ihrer Komponente
In der Informatik hört man vielleicht von einer„Zustandsmaschine“, die sich in einem von mehreren „Zuständen“ befindet. Wenn Sie mit einem Designer zusammenarbeiten, haben Sie vielleicht Mockups für verschiedene „visuelle Zustände“ gesehen. React steht an der Schnittstelle von Design und Informatik, daher sind beide Ideen Quellen der Inspiration.
Zuerst müssen Sie alle verschiedenen „Zustände“ der Benutzeroberfläche visualisieren, die der Benutzer sehen könnte:
- Leer: Das Formular hat einen deaktivierten „Absenden“-Button.
- Eingabe: Das Formular hat einen aktivierten „Absenden“-Button.
- Wird gesendet: Das Formular ist vollständig deaktiviert. Ein Ladekreis wird angezeigt.
- Erfolg: Statt des Formulars wird eine „Danke“-Nachricht angezeigt.
- Fehler: Gleich wie der Eingabe-Zustand, aber mit einer zusätzlichen Fehlermeldung.
Genau wie ein Designer möchten Sie die verschiedenen Zustände „mocken“ oder „Mocks“ erstellen, bevor Sie Logik hinzufügen. Hier ist zum Beispiel ein Mock für nur den visuellen Teil des Formulars. Dieser Mock wird durch eine Prop namensstatusmit einem Standardwert von'empty'gesteuert:
Sie können diese Prop beliebig nennen, die Benennung ist nicht wichtig. Versuchen Sie,status = 'empty'instatus = 'success'zu ändern, um die Erfolgsmeldung erscheinen zu lassen. Mocking ermöglicht es Ihnen, schnell an der Benutzeroberfläche zu iterieren, bevor Sie Logik einbinden. Hier ist ein ausgefeilterer Prototyp derselben Komponente, der immer noch durch diestatusProp „gesteuert“ wird:
Schritt 2: Bestimmen, was diese Zustandsänderungen auslöst
Sie können Zustandsaktualisierungen als Reaktion auf zwei Arten von Eingaben auslösen:
- Menschliche Eingaben,wie das Klicken auf einen Button, das Tippen in ein Feld, das Navigieren über einen Link.
- Computereingaben,wie das Eintreffen einer Netzwerkantwort, das Abschließen eines Timeouts, das Laden eines Bildes.


Illustriert vonRachel Lee Nabors
In beiden Fällenmüssen SieZustandsvariablensetzen, um die Benutzeroberfläche zu aktualisieren.Für das Formular, das Sie entwickeln, müssen Sie den Zustand als Reaktion auf einige verschiedene Eingaben ändern:
- Ändern der Texteingabe(durch den Benutzer) sollte den Zustand vonLeer zu Am Tippenwechseln oder zurück, je nachdem, ob das Textfeld leer ist oder nicht.
- Klicken auf den Senden-Button(durch den Benutzer) sollte den Zustand zuWird gesendetwechseln.
- Erfolgreiche Netzwerkantwort(vom Computer) sollte den Zustand zuErfolgwechseln.
- Fehlgeschlagene Netzwerkantwort(vom Computer) sollte den Zustand zuFehlerwechseln, mit der entsprechenden Fehlermeldung.
Hinweis
Beachten Sie, dass Benutzereingaben oftEvent-Handlererfordern!
Um diesen Ablauf zu visualisieren, versuchen Sie, jeden Zustand auf Papier als beschrifteten Kreis und jede Änderung zwischen zwei Zuständen als Pfeil zu zeichnen. Auf diese Weise können Sie viele Abläufe skizzieren und Fehler lange vor der Implementierung ausmerzen.


Formularzustände
Schritt 3: Den Zustand im Speicher mituseState
Als nächstes müssen Sie die visuellen Zustände Ihrer Komponente im Speicher mituseStaterepräsentieren. Einfachheit ist entscheidend: Jedes Stück State ist ein „bewegliches Teil“, undSie möchten so wenige „bewegliche Teile“ wie möglich.Mehr Komplexität führt zu mehr Fehlern!
Beginnen Sie mit dem State, derunbedingtvorhanden sein muss. Zum Beispiel müssen Sie dieanswerfür die Eingabe und denerror(falls vorhanden) speichern, um den letzten Fehler zu speichern:
Dann benötigen Sie eine Zustandsvariable, die darstellt, welchen der visuellen Zustände Sie anzeigen möchten. Es gibt normalerweise mehr als eine Möglichkeit, dies im Speicher darzustellen, daher müssen Sie damit experimentieren.
Wenn es Ihnen schwerfällt, sofort die beste Methode zu finden, beginnen Sie damit, genügend Zustände hinzuzufügen, sodass Siedefinitivsicher sind, dass alle möglichen visuellen Zustände abgedeckt sind:
Ihre erste Idee wird wahrscheinlich nicht die beste sein, aber das ist in Ordnung – das Refaktorieren des Zustands ist Teil des Prozesses!
Schritt 4: Entfernen Sie alle nicht wesentlichen Zustandsvariablen
Sie sollten Duplikate im Zustandsinhalt vermeiden, sodass Sie nur das Wesentliche verfolgen. Wenn Sie etwas Zeit in die Refaktorierung Ihrer Zustandsstruktur investieren, werden Ihre Komponenten leichter zu verstehen sein, Duplikate reduziert und unbeabsichtigte Bedeutungen vermieden. Ihr Ziel ist es,Fälle zu verhindern, in denen der Zustand im Speicher keine gültige Benutzeroberfläche darstellt, die ein Benutzer sehen sollte.(Sie möchten beispielsweise niemals eine Fehlermeldung anzeigen und gleichzeitig die Eingabe deaktivieren, da der Benutzer sonst den Fehler nicht korrigieren kann!)
Hier sind einige Fragen, die Sie zu Ihren Zustandsvariablen stellen können:
- Verursacht dieser Zustand ein Paradoxon?Beispielsweise können
isTypingundisSubmittingnicht beidetruesein. Ein Paradoxon bedeutet normalerweise, dass der Zustand nicht ausreichend eingeschränkt ist. Es gibt vier mögliche Kombinationen zweier Boolescher Werte, aber nur drei entsprechen gültigen Zuständen. Um den "unmöglichen" Zustand zu entfernen, kannst du diese zu einemstatuskombinieren, der einer von drei Werten sein muss:'typing','submitting'oder'success'. - Ist dieselbe Information bereits in einer anderen Zustandsvariablen verfügbar?Ein weiteres Paradoxon:
isEmptyundisTypingkönnen nicht gleichzeitigtruesein. Wenn du sie als separate Zustandsvariablen behältst, riskierst du, dass sie nicht synchron sind und Fehler verursachen. Glücklicherweise kannst duisEmptyentfernen und stattdessenanswer.length === 0prüfen. - Kannst du dieselbe Information aus dem Gegenteil einer anderen Zustandsvariablen erhalten?
isErrorist nicht nötig, weil du stattdessenerror !== nullprüfen kannst.
Nach dieser Bereinigung bleiben 3 (von ursprünglich 7!)essentielleZustandsvariablen übrig:
Du weißt, dass sie essentiell sind, weil du keine davon entfernen kannst, ohne die Funktionalität zu beeinträchtigen.
Schritt 5: Ereignishandler mit der Zustandsänderung verbinden
Erstelle schließlich Ereignishandler, die den Zustand aktualisieren. Unten siehst du das fertige Formular mit allen verbundenen Ereignishandlern:
Obwohl dieser Code länger ist als das ursprüngliche imperative Beispiel, ist er viel weniger anfällig für Fehler. Indem du alle Interaktionen als Zustandsänderungen ausdrückst, kannst du später neue visuelle Zustände einführen, ohne bestehende zu brechen. Es ermöglicht dir auch zu ändern, was in jedem Zustand angezeigt werden soll, ohne die Logik der Interaktion selbst zu ändern.
Zusammenfassung
- Deklarative Programmierung bedeutet, die Benutzeroberfläche für jeden visuellen Zustand zu beschreiben, anstatt die Benutzeroberfläche zu micromanagen (imperativ).
- Bei der Entwicklung einer Komponente:
- Identifiziere alle ihre visuellen Zustände.
- Bestimme die menschlichen und computerbasierten Auslöser für Zustandsänderungen.
- Modelliere den Zustand mit
useState.
Try out some challenges
Challenge 1 of 3:Add and remove a CSS class #
Make it so that clicking on the picture removes the background--active CSS class from the outer <div>, but adds the picture--active class to the <img>. Clicking the background again should restore the original CSS classes.
Visually, you should expect that clicking on the picture removes the purple background and highlights the picture border. Clicking outside the picture highlights the background, but removes the picture border highlight.
