React bietet eine leistungsstarke Möglichkeit zur Verwaltung von Lade- und Fehlerzuständen in Anwendungen durch die Verwendung von Suspense und Error Boundaries. Diese beiden Konzepte ermöglichen es, die Benutzererfahrung zu optimieren, indem Lade- und Fehlerzustände elegant gehandhabt werden. React Suspense hilft dabei, Daten asynchron zu laden, ohne den gesamten Rendering-Prozess zu blockieren, und Fehler Boundaries bieten eine Möglichkeit, auf Fehler zu reagieren, indem sie alternative Darstellungen anbieten. Die Integration dieser beiden Techniken erfordert ein gründliches Verständnis der Funktionsweise von React und den damit verbundenen Bibliotheken.
Setup eines Suspense-Boundaries
Zunächst muss ein Suspense Boundary eingerichtet werden. Ein Suspense Boundary ist ein Container, der als Fallback dient, falls ein Kindkomponent noch Daten lädt. Wenn ein Kind innerhalb des Boundaries Daten abruft, wird das Fallback angezeigt, bis alle benötigten Daten erfolgreich geladen wurden. Sobald die Daten bereit sind, wird die vollständige Anzeige der Kindkomponenten wiederhergestellt.
Um ein Suspense Boundary zu verwenden, muss der Code wie folgt strukturiert werden:
-
Kopieren Sie den Ordner
Chapter06_3und erstellen Sie einen neuen OrdnerChapter06_4. -
Öffnen Sie den Ordner
Chapter06_4in Visual Studio Code. -
Bearbeiten Sie die Datei
src/App.jsxund importieren SieSuspenseausreact: -
Ändern Sie den
App-Komponenten, um den Post-Feed innerhalb eines Suspense Boundaries zu rendern und eine Ladeanzeige als Fallback bereitzustellen: -
Im nächsten Schritt wird der PostFeed-Komponent so angepasst, dass er den
useSuspenseQueryHook aus der@tanstack/react-query-Bibliothek verwendet: -
Passen Sie den Hook an, um die Daten abzurufen:
-
Da der Suspense Hook bereits die Ladezustände behandelt, kann die vorherige Fehlerbehandlung und Ladeanzeige entfernt werden.
Durch diesen Prozess wird der Post-Feed innerhalb eines Suspense Boundaries geladen. Wenn die Daten noch nicht verfügbar sind, zeigt die App eine einzige Ladeanzeige statt mehreren an, was das Nutzererlebnis deutlich verbessert.
Simulation von langsamen Netzwerken
In einer realen Umgebung müssen Entwickler die Auswirkungen von Netzwerkverzögerungen berücksichtigen, da die Ladezeiten in der Regel nicht so schnell sind wie bei einer lokalen Entwicklung. In den Chrome DevTools lässt sich eine simulierte Netzwerkverzögerung einrichten, um die Ladegeschwindigkeit zu verlangsamen und das Verhalten der App unter weniger idealen Bedingungen zu testen. Dies ist besonders wichtig, um sicherzustellen, dass die Benutzeroberfläche auch bei langsamen Netzwerken korrekt funktioniert.
-
Öffnen Sie die Chrome-Entwicklertools und gehen Sie zum Tab "Netzwerk".
-
Wählen Sie die Option "No throttling" und stellen Sie sie auf das 3G-Netzwerk-Preset.
-
Aktualisieren Sie die Seite und beobachten Sie, wie die Anwendung mit langsamen Verbindungen umgeht.
Diese Simulation ist von entscheidender Bedeutung, um zu verstehen, wie die App unter realistischen Netzwerkbedingungen funktioniert.
Einrichtung eines Error Boundaries
Während Suspense eine Möglichkeit bietet, Ladezustände zu behandeln, müssen Fehler ebenfalls effektiv abgefangen werden. Dies geschieht mit einem Error Boundary. Ein Error Boundary wird ähnlich wie ein Suspense Boundary eingesetzt, reagiert jedoch auf Fehlerzustände und nicht auf Ladezustände. Wenn ein Fehler auftritt, wird der Boundary aktiviert und zeigt eine Fehleranzeige mit einer Möglichkeit zur Fehlerbehebung an.
-
Installieren Sie das
react-error-boundary-Paket: -
Erstellen Sie eine neue Datei
src/FetchErrorNotice.jsxund definieren Sie einen Komponent, der eineresetErrorBoundary-Funktion akzeptiert. Diese Funktion wird verwendet, um den Fehler zu beheben und die Anfrage erneut auszuführen: -
Bearbeiten Sie die
src/App.jsx, um den Error Boundary zu integrieren und eine Möglichkeit zu bieten, die Abfrage bei einem Fehler zurückzusetzen: -
Um eine vollständige Fehlerbehandlung zu ermöglichen, wird der
ErrorBoundaryverwendet, um die App-Komponente zu umschließen, die durch denQueryErrorResetBoundaryunterstützt wird:
Wenn ein Fehler im Abrufen der Daten auftritt, zeigt die App eine Fehlermeldung zusammen mit einer Schaltfläche „Try again“ an. Durch das Klicken auf diese Schaltfläche wird die Abfrage zurückgesetzt und die Posts erneut geladen.
Fazit
Mit React Suspense und Error Boundaries können Entwickler auf elegante Weise mit Lade- und Fehlerzuständen umgehen. React Suspense erleichtert das Laden von Daten, indem es einen Fallback bietet, der die Benutzeroberfläche nicht blockiert, während die Daten geladen werden. Error Boundaries hingegen stellen sicher, dass Fehler in der Anwendung abgefangen und die Benutzerfreundlichkeit auch bei fehlerhaften Abfragen gewährleistet wird. Diese Techniken sind entscheidend, um robuste und benutzerfreundliche Anwendungen zu erstellen, die auch unter schwierigen Netzwerkbedingungen zuverlässig funktionieren.
Wie man den Local Storage Hook effektiv in React-Projekten einsetzt
Die Verwaltung des Zustands in modernen Webanwendungen stellt eine der größten Herausforderungen dar, insbesondere wenn es darum geht, Benutzerdaten zwischen den Sitzungen persistent zu speichern. Der Local Storage Hook bietet eine elegante Lösung, um Daten dauerhaft im Browser zu speichern, ohne dass der Benutzer bei jedem Laden der Seite erneut eingeloggt werden muss. In diesem Kapitel wird gezeigt, wie man den Local Storage Hook in einem React-Projekt implementiert und warum er eine wertvolle Alternative zu Context Hooks und State Hooks darstellt.
Zunächst einmal ersetzt der Local Storage Hook die traditionelle Nutzung des useState-Hooks, um Benutzerdaten zu speichern. Ein typisches Beispiel ist das Speichern des Benutzernamens eines Nutzers, der sich in einer Anwendung anmeldet. Anstatt den Benutzernamen nur während einer Sitzung im useState-Hook zu halten, lässt sich dieser Wert mithilfe des useLocalStorage-Hooks in der Local Storage API des Browsers speichern, was bedeutet, dass der Benutzer auch nach dem Neuladen der Seite eingeloggt bleibt. Dies erhöht die Benutzerfreundlichkeit und sorgt dafür, dass der Benutzerstatus über mehrere Sitzungen hinweg erhalten bleibt.
Implementierung des Local Storage Hooks
Nehmen wir an, Sie möchten den Benutzernamen in einer React-Anwendung speichern. Zuerst ersetzen wir den herkömmlichen State Hook durch den Local Storage Hook. Anstelle von:
wird dieser Code zu:
Hierbei wird der username-Wert in der Local Storage des Browsers gespeichert und steht über die gesamte Lebensdauer der Sitzung hinaus zur Verfügung. Dies ermöglicht es, dass der Benutzer auch nach einem Seiten-Reload angemeldet bleibt, ohne dass eine erneute Anmeldung erforderlich ist.
Anwendungsbeispiel in verschiedenen Komponenten
Ein praktisches Beispiel für die Verwendung des useLocalStorage-Hooks findet sich in der Implementierung von Benutzeranmeldungen, Registrierungen und Logouts in der Anwendung. In der UserBar-Komponente, die den Benutzernamen anzeigt, kann der Hook wie folgt genutzt werden:
In der Login-Komponente wird der Benutzername in den Local Storage gesetzt, sobald der Benutzer sich einloggt:
Vorteile der Verwendung von Local Storage
Die Verwendung des Local Storage Hooks bietet mehrere Vorteile gegenüber dem traditionellen State-Management. Zunächst einmal bleibt der Benutzerstatus auch nach einem Seitenreload erhalten, was eine bessere Benutzererfahrung ermöglicht. Dies ist besonders nützlich bei Webanwendungen, bei denen Benutzer oft zwischen Seiten wechseln oder die Seite neu laden müssen. Die Speicherung im Local Storage ist zudem einfach und erfordert keine zusätzliche Backend-Unterstützung, was die Implementierung vereinfacht und die Entwicklung beschleunigt.
Ein weiterer Vorteil ist die Reduzierung der Komplexität, da der Context Hook nicht mehr benötigt wird, um den Benutzernamen in der gesamten Anwendung verfügbar zu machen. Anstatt Context-Provider und Consumer einzuführen, wird der Wert einfach direkt im Local Storage gespeichert und kann überall in der Anwendung abgerufen werden, ohne dass eine zentrale Verwaltung erforderlich ist.
Weitere Verbesserungen: Undo/Redo mit useHistoryState
Ein weiterer interessanter Aspekt, der in modernen React-Projekten oft benötigt wird, ist die Möglichkeit, Änderungen am Zustand rückgängig zu machen oder wiederherzustellen. Der useHistoryState-Hook erweitert den useState-Hook um Undo- und Redo-Funktionalitäten. Dieser Hook speichert den Zustand und bietet Funktionen, um zwischen verschiedenen Zuständen hin- und herzuwechseln. Beispielsweise kann eine CreatePost-Komponente so gestaltet werden, dass sie den Post-Inhalt speichert und dem Benutzer erlaubt, seine Änderungen rückgängig zu machen oder wiederherzustellen.
Der useHistoryState-Hook bietet folgende Funktionalitäten:
Durch das Hinzufügen von Undo- und Redo-Schaltflächen kann der Benutzer die Eingabe zurücksetzen, ohne die gesamte Seite neu laden zu müssen. Dies erhöht die Interaktivität der Anwendung und verbessert das Benutzererlebnis.
Implementierung von Debouncing für Undo/Redo
Ein häufiges Problem bei der Verwendung von Undo/Redo-Funktionen ist die Überlastung des Speichers mit zu vielen kleinen Änderungen. Um dies zu vermeiden, kann eine Technik namens Debouncing eingesetzt werden. Debouncing sorgt dafür, dass Änderungen nur dann zum Undo-Redo-Verlauf hinzugefügt werden, wenn eine bestimmte Zeitspanne ohne neue Eingaben vergangen ist. Dies verhindert unnötige Änderungen und optimiert die Performance.
Für diese Funktionalität kann der use-debounce Hook verwendet werden, der Änderungen verzögert, bis der Benutzer eine bestimmte Zeit lang keine Eingabe gemacht hat. Dies ist besonders nützlich in Textfeldern, in denen Benutzer längere Inhalte eingeben.
Fazit
Die Kombination von useLocalStorage und useHistoryState bietet eine leistungsstarke Möglichkeit, Zustände in React-Anwendungen zu verwalten, die sowohl persistent als auch rückgängig gemacht werden können. Während der useLocalStorage-Hook eine einfache Möglichkeit bietet, Benutzerdaten zu speichern, sorgt der useHistoryState-Hook für eine flexible Verwaltung von Änderungen. Durch den Einsatz von Debouncing kann zudem sichergestellt werden, dass die Anwendung auch bei häufigen Änderungen performant bleibt.
Um diese Techniken optimal zu nutzen, sollten Entwickler verstehen, dass der Local Storage zwar eine einfache Lösung für die Persistenz von Daten darstellt, aber auch seine Grenzen hat, insbesondere bei sehr großen Datenmengen. Es ist wichtig, den Local Storage sparsam zu verwenden und darauf zu achten, dass er keine sensiblen oder großen Daten speichert, um die Performance und Sicherheit der Anwendung zu gewährleisten.
Wie man benutzerdefinierte Hooks in React erstellt und testet
In der React-Entwicklung ist das Erstellen und Testen von benutzerdefinierten Hooks eine entscheidende Fähigkeit, die es Entwicklern ermöglicht, wiederverwendbare Logik zu erstellen und die Wartbarkeit von Anwendungen zu erhöhen. Ein benutzerdefinierter Hook ist im Wesentlichen eine Funktion, die React-spezifische Logik kapselt, so dass diese an mehreren Stellen in einer Anwendung wiederverwendet werden kann. Im Folgenden wird erläutert, wie benutzerdefinierte Hooks aus bestehendem Code extrahiert werden und wie sie getestet werden können.
Ein einfaches Beispiel für einen benutzerdefinierten Hook könnte das Verwalten von Benutzerstatus und -aktionen sein, etwa die Registrierung, Anmeldung und Abmeldung. Ein solcher Hook könnte die Verbindung zu einem Authentifizierungsdienst verwalten, den aktuellen Benutzerstatus zurückgeben und Funktionen bereitstellen, um den Benutzer anzumelden oder abzumelden.
Der erste Schritt beim Erstellen eines benutzerdefinierten Hooks ist, die Logik, die in mehreren Komponenten verwendet werden soll, zu extrahieren und in einer separaten Funktion zu kapseln. Dies hilft, den Code sauber und wiederverwendbar zu halten. Ein Beispiel für das Extrahieren eines benutzerdefinierten Hooks aus bestehendem Code könnte folgendermaßen aussehen:
In diesem Beispiel wird die Benutzerdatenlogik in einem benutzerdefinierten Hook useUser extrahiert, der dann in verschiedenen Komponenten verwendet werden kann. Dieser Hook kapselt sowohl den Zustand des Benutzers als auch die Logik zum Anmelden und Abmelden.
Nach der Extraktion des benutzerdefinierten Hooks ist es entscheidend, Tests zu schreiben, um sicherzustellen, dass der Hook korrekt funktioniert. In diesem Zusammenhang ist Vitest ein hilfreiches Tool. Vitest ist ein modernes Test-Framework, das eng mit der React Testing Library integriert ist und speziell für Tests von React-Komponenten und -Hooks entwickelt wurde.
Ein einfacher Test für den oben erstellten useUser Hook könnte folgendermaßen aussehen:
In diesem Beispiel wird die renderHook-Funktion von der React Testing Library verwendet, um den Hook zu rendern und zu testen, ob die Benutzerdaten erfolgreich geladen werden. Die waitForNextUpdate-Funktion wartet darauf, dass der Hook seinen Zustand aktualisiert, bevor der Test fortgesetzt wird.
Ein weiteres häufiges Szenario bei der Arbeit mit benutzerdefinierten Hooks ist der Umgang mit asynchronen Operationen, wie zum Beispiel das Abrufen von Daten von einem Server. In diesem Fall können sogenannte "Fake-Timer" verwendet werden, um Zeitüberschreitungen oder verzögerte Antworten zu simulieren, ohne auf echte Wartezeiten angewiesen zu sein. Dies kann insbesondere dann nützlich sein, wenn der Hook auf verzögerte Daten oder Ereignisse wartet, wie es bei der Geschichte einer Undo/Redo-Funktionalität der Fall ist. Mit Vitest können Sie solche Operationen leicht mocken und testen.
Ein weiterer wichtiger Aspekt beim Testen von benutzerdefinierten Hooks ist der Umgang mit React Context. Wenn der Hook auf Werte aus einem Context zugreift, wie beispielsweise auf Benutzerdaten oder die aktuelle Sprache, muss der Test sicherstellen, dass der Context korrekt bereitgestellt und abgerufen wird. In diesem Fall könnte der Test folgendermaßen aussehen:
In diesem Test wird der UserContextProvider verwendet, um den Kontext für den useUser Hook bereitzustellen. Die Testkomponente greift dann auf die Benutzerdaten zu und prüft, ob sie korrekt angezeigt werden.
Zusätzlich zu den grundlegenden Tests für benutzerdefinierte Hooks ist es wichtig zu beachten, dass das Testen von Hooks, die Zustandsänderungen oder asynchrone Vorgänge beinhalten, mit speziellen Werkzeugen wie waitFor oder act erfolgt, um sicherzustellen, dass der Zustand korrekt aktualisiert wird und alle Nebenwirkungen berücksichtigt werden. Der Einsatz von Fake-Timern in Vitest ermöglicht es außerdem, zeitabhängige Logik zu testen, ohne auf echte Zeitverzögerungen angewiesen zu sein.
In vielen Fällen ist es nicht notwendig, Tests für Bibliotheks-Hooks zu schreiben, die keine eigene Logik enthalten, wie es bei den meisten API-Hooks der Fall ist. Der Testaufwand konzentriert sich vielmehr auf die Logik, die wir in benutzerdefinierte Hooks integriert haben.
Abschließend lässt sich sagen, dass das Erstellen und Testen von benutzerdefinierten Hooks eine zentrale Fähigkeit für React-Entwickler darstellt. Das Kapseln von Logik in benutzerdefinierten Hooks verbessert die Wartbarkeit und Wiederverwendbarkeit des Codes, während das Testen sicherstellt, dass diese Logik auch nach Refaktorierungen oder Änderungen weiterhin korrekt funktioniert. Diese Fähigkeiten sind besonders wichtig in größeren Anwendungen, in denen eine Vielzahl von benutzerdefinierten Hooks definiert werden müssen.
Wie man Diabetikerfreundliche Vietnamesische Gerichte zubereitet: Ein Balanceakt zwischen Geschmack und Gesundheit
Wie bewertet man Verletzte und reagiert effektiv bei Notfällen?
Wie umgehen wir den Skeptizismus über das, was Dinge sind?

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский