Erschließen Sie das Potenzial wiederverwendbarer Logik in Ihren React-Anwendungen mit Custom Hooks. Lernen Sie, wie Sie Custom Hooks für sauberen, wartbareren Code erstellen und nutzen.
Custom Hooks: Wiederverwendbare Logikmuster in React
React Hooks haben die Art und Weise, wie wir React-Komponenten schreiben, revolutioniert, indem sie Zustands- und Lebenszyklus-Features in funktionale Komponenten einführten. Unter den vielen Vorteilen, die sie bieten, stechen Custom Hooks als ein mächtiger Mechanismus zur Extraktion und Wiederverwendung von Logik über mehrere Komponenten hinweg hervor. Dieser Blogbeitrag wird tief in die Welt der Custom Hooks eintauchen und ihre Vorteile, Erstellung und Nutzung anhand praktischer Beispiele untersuchen.
Was sind Custom Hooks?
Im Wesentlichen ist ein Custom Hook eine JavaScript-Funktion, die mit dem Wort „use“ beginnt und andere Hooks aufrufen kann. Sie ermöglichen es Ihnen, Komponentenlogik in wiederverwendbare Funktionen zu extrahieren. Dies ist eine leistungsstarke Methode, um zustandsbehaftete Logik, Nebeneffekte oder andere komplexe Verhaltensweisen zwischen Komponenten zu teilen, ohne auf Render Props, Higher-Order Components oder andere komplexe Muster zurückgreifen zu müssen.
Schlüsselmerkmale von Custom Hooks:
- Namenskonvention: Custom Hooks müssen mit dem Wort „use“ beginnen. Dies signalisiert React, dass die Funktion Hooks enthält und den Regeln für Hooks folgen sollte.
- Wiederverwendbarkeit: Der Hauptzweck besteht darin, wiederverwendbare Logik zu kapseln, um die gemeinsame Nutzung von Funktionalität zwischen Komponenten zu erleichtern.
- Zustandsbehaftete Logik: Custom Hooks können ihren eigenen Zustand mit dem
useState
-Hook verwalten, was es ihnen ermöglicht, komplexes zustandsbehaftetes Verhalten zu kapseln. - Nebeneffekte: Sie können auch Nebeneffekte mit dem
useEffect
-Hook ausführen, was die Integration mit externen APIs, Datenabruf und mehr ermöglicht. - Komponierbarkeit: Custom Hooks können andere Hooks aufrufen, sodass Sie komplexe Logik durch die Zusammensetzung kleinerer, fokussierterer Hooks aufbauen können.
Vorteile der Verwendung von Custom Hooks
Custom Hooks bieten mehrere signifikante Vorteile in der React-Entwicklung:
- Wiederverwendbarkeit von Code: Der offensichtlichste Vorteil ist die Möglichkeit, Logik über mehrere Komponenten hinweg wiederzuverwenden. Dies reduziert Codeduplizierung und fördert eine DRY (Don't Repeat Yourself)-Codebasis.
- Verbesserte Lesbarkeit: Durch das Extrahieren komplexer Logik in separate Custom Hooks werden Ihre Komponenten sauberer und leichter verständlich. Die Kernlogik der Komponente bleibt auf das Rendern der Benutzeroberfläche fokussiert.
- Erhöhte Wartbarkeit: Wenn Logik in Custom Hooks gekapselt ist, können Änderungen und Fehlerbehebungen an einer einzigen Stelle angewendet werden, was das Risiko der Einführung von Fehlern in mehreren Komponenten verringert.
- Testbarkeit: Custom Hooks können leicht isoliert getestet werden, um sicherzustellen, dass die wiederverwendbare Logik unabhängig von den Komponenten, die sie verwenden, korrekt funktioniert.
- Vereinfachte Komponenten: Custom Hooks helfen dabei, Komponenten zu entrümpeln, wodurch sie weniger wortreich und stärker auf ihren Hauptzweck ausgerichtet werden.
Ihren ersten Custom Hook erstellen
Lassen Sie uns die Erstellung eines Custom Hooks mit einem praktischen Beispiel veranschaulichen: ein Hook, der die Fenstergröße verfolgt.
Beispiel: useWindowSize
Dieser Hook gibt die aktuelle Breite und Höhe des Browserfensters zurück. Er aktualisiert diese Werte auch, wenn die Größe des Fensters geändert wird.
import { useState, useEffect } from 'react';
function useWindowSize() {
const [windowSize, setWindowSize] = useState({
width: window.innerWidth,
height: window.innerHeight,
});
useEffect(() => {
function handleResize() {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight,
});
}
window.addEventListener('resize', handleResize);
// Event-Listener bei der Bereinigung entfernen
return () => window.removeEventListener('resize', handleResize);
}, []); // Leeres Array stellt sicher, dass der Effekt nur beim Mounten ausgeführt wird
return windowSize;
}
export default useWindowSize;
Erklärung:
- Notwendige Hooks importieren: Wir importieren
useState
unduseEffect
aus React. - Den Hook definieren: Wir erstellen eine Funktion namens
useWindowSize
und halten uns dabei an die Namenskonvention. - Zustand initialisieren: Wir verwenden
useState
, um denwindowSize
-Zustand mit der anfänglichen Breite und Höhe des Fensters zu initialisieren. - Event-Listener einrichten: Wir verwenden
useEffect
, um einen Resize-Event-Listener zum Fenster hinzuzufügen. Wenn die Größe des Fensters geändert wird, aktualisiert diehandleResize
-Funktion denwindowSize
-Zustand. - Bereinigung: Wir geben eine Bereinigungsfunktion von
useEffect
zurück, um den Event-Listener zu entfernen, wenn die Komponente unmounted wird. Dies verhindert Speicherlecks. - Rückgabewerte: Der Hook gibt das
windowSize
-Objekt zurück, das die aktuelle Breite und Höhe des Fensters enthält.
Den Custom Hook in einer Komponente verwenden
Nachdem wir unseren Custom Hook erstellt haben, wollen wir sehen, wie man ihn in einer React-Komponente verwendet.
import React from 'react';
import useWindowSize from './useWindowSize';
function MyComponent() {
const { width, height } = useWindowSize();
return (
Fensterbreite: {width}px
Fensterhöhe: {height}px
);
}
export default MyComponent;
Erklärung:
- Den Hook importieren: Wir importieren den
useWindowSize
Custom Hook. - Den Hook aufrufen: Wir rufen den
useWindowSize
-Hook innerhalb der Komponente auf. - Auf Werte zugreifen: Wir destrukturieren das zurückgegebene Objekt, um die Werte für
width
undheight
zu erhalten. - Werte rendern: Wir rendern die Werte für Breite und Höhe in der Benutzeroberfläche der Komponente.
Jede Komponente, die useWindowSize
verwendet, wird automatisch aktualisiert, wenn sich die Fenstergröße ändert.
Komplexere Beispiele
Lassen Sie uns einige fortgeschrittenere Anwendungsfälle für Custom Hooks untersuchen.
Beispiel: useLocalStorage
Dieser Hook ermöglicht es Ihnen, Daten einfach im Local Storage zu speichern und abzurufen.
import { useState, useEffect } from 'react';
function useLocalStorage(key, initialValue) {
// Zustand zum Speichern unseres Wertes
// Initialwert an useState übergeben, damit die Logik nur einmal ausgeführt wird
const [storedValue, setStoredValue] = useState(() => {
try {
// Aus dem Local Storage nach Schlüssel abrufen
const item = window.localStorage.getItem(key);
// Gespeichertes JSON parsen oder, falls keines vorhanden, initialValue zurückgeben
return item ? JSON.parse(item) : initialValue;
} catch (error) {
// Bei einem Fehler ebenfalls initialValue zurückgeben
console.log(error);
return initialValue;
}
});
// Eine umschlossene Version der Setter-Funktion von useState zurückgeben, die ...
// ... den neuen Wert im localStorage speichert.
const setValue = (value) => {
try {
// Wert als Funktion zulassen, um dieselbe API wie useState zu haben
const valueToStore = value instanceof Function ? value(storedValue) : value;
// Im Local Storage speichern
window.localStorage.setItem(key, JSON.stringify(valueToStore));
// Zustand speichern
setStoredValue(valueToStore);
} catch (error) {
// Eine fortgeschrittenere Implementierung würde den Fehlerfall behandeln
console.log(error);
}
};
useEffect(() => {
try {
const item = window.localStorage.getItem(key);
setStoredValue(item ? JSON.parse(item) : initialValue);
} catch (error) {
console.log(error);
}
}, [key, initialValue]);
return [storedValue, setValue];
}
export default useLocalStorage;
Verwendung:
import React from 'react';
import useLocalStorage from './useLocalStorage';
function MyComponent() {
const [name, setName] = useLocalStorage('name', 'Guest');
return (
Hallo, {name}!
setName(e.target.value)}
/>
);
}
export default MyComponent;
Beispiel: useFetch
Dieser Hook kapselt die Logik zum Abrufen von Daten von einer API.
import { useState, useEffect } from 'react';
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchData() {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP-Fehler! Status: ${response.status}`);
}
const json = await response.json();
setData(json);
setLoading(false);
} catch (error) {
setError(error);
setLoading(false);
}
}
fetchData();
}, [url]);
return { data, loading, error };
}
export default useFetch;
Verwendung:
import React from 'react';
import useFetch from './useFetch';
function MyComponent() {
const { data, loading, error } = useFetch('https://jsonplaceholder.typicode.com/todos/1');
if (loading) return Lade...
;
if (error) return Fehler: {error.message}
;
return (
Titel: {data.title}
Abgeschlossen: {data.completed ? 'Ja' : 'Nein'}
);
}
export default MyComponent;
Best Practices für Custom Hooks
Um sicherzustellen, dass Ihre Custom Hooks effektiv und wartbar sind, befolgen Sie diese Best Practices:
- Halten Sie sie fokussiert: Jeder Custom Hook sollte einen einzigen, klar definierten Zweck haben. Vermeiden Sie die Erstellung übermäßig komplexer Hooks, die zu viel auf einmal versuchen.
- Dokumentieren Sie Ihre Hooks: Stellen Sie eine klare und prägnante Dokumentation für jeden Custom Hook bereit, die dessen Zweck, Eingaben und Ausgaben erklärt.
- Testen Sie Ihre Hooks: Schreiben Sie Unit-Tests für Ihre Custom Hooks, um sicherzustellen, dass sie korrekt und zuverlässig funktionieren.
- Verwenden Sie beschreibende Namen: Wählen Sie beschreibende Namen für Ihre Custom Hooks, die ihren Zweck klar angeben.
- Behandeln Sie Fehler elegant: Implementieren Sie eine Fehlerbehandlung in Ihren Custom Hooks, um unerwartetes Verhalten zu vermeiden und informative Fehlermeldungen bereitzustellen.
- Bedenken Sie die Wiederverwendbarkeit: Gestalten Sie Ihre Custom Hooks mit Blick auf Wiederverwendbarkeit. Machen Sie sie generisch genug, um in mehreren Komponenten verwendet werden zu können.
- Vermeiden Sie übermäßige Abstraktion: Erstellen Sie keine Custom Hooks für einfache Logik, die leicht innerhalb einer Komponente gehandhabt werden kann. Extrahieren Sie nur Logik, die wirklich wiederverwendbar und komplex ist.
Häufige Fallstricke, die es zu vermeiden gilt
- Die Regeln von Hooks brechen: Rufen Sie Hooks immer auf der obersten Ebene Ihrer Custom-Hook-Funktion auf und nur aus React-Funktionskomponenten oder anderen Custom Hooks.
- Abhängigkeiten in useEffect ignorieren: Stellen Sie sicher, dass Sie alle notwendigen Abhängigkeiten in das Abhängigkeits-Array des
useEffect
-Hooks aufnehmen, um veraltete Closures und unerwartetes Verhalten zu vermeiden. - Unendliche Schleifen erstellen: Seien Sie vorsichtig beim Aktualisieren des Zustands innerhalb eines
useEffect
-Hooks, da dies leicht zu unendlichen Schleifen führen kann. Stellen Sie sicher, dass die Aktualisierung bedingt ist und auf Änderungen in den Abhängigkeiten basiert. - Die Bereinigung vergessen: Fügen Sie immer eine Bereinigungsfunktion in
useEffect
ein, um Event-Listener zu entfernen, Abonnements zu kündigen und andere Bereinigungsaufgaben durchzuführen, um Speicherlecks zu verhindern.
Fortgeschrittene Muster
Komposition von Custom Hooks
Custom Hooks können miteinander kombiniert werden, um komplexere Logik zu erstellen. Sie könnten zum Beispiel einen useLocalStorage
-Hook mit einem useFetch
-Hook kombinieren, um abgerufene Daten automatisch im Local Storage zu speichern.
Logik zwischen Hooks teilen
Wenn mehrere Custom Hooks gemeinsame Logik teilen, können Sie diese Logik in eine separate Hilfsfunktion extrahieren und in beiden Hooks wiederverwenden.
Context mit Custom Hooks verwenden
Custom Hooks können in Verbindung mit React Context verwendet werden, um auf den globalen Zustand zuzugreifen und ihn zu aktualisieren. Dies ermöglicht es Ihnen, wiederverwendbare Komponenten zu erstellen, die den globalen Zustand der Anwendung kennen und mit ihm interagieren können.
Beispiele aus der Praxis
Hier sind einige Beispiele, wie Custom Hooks in realen Anwendungen verwendet werden können:
- Formularvalidierung: Erstellen Sie einen
useForm
-Hook, um den Formularzustand, die Validierung und das Absenden zu handhaben. - Authentifizierung: Implementieren Sie einen
useAuth
-Hook, um die Benutzerauthentifizierung und -autorisierung zu verwalten. - Theme-Verwaltung: Entwickeln Sie einen
useTheme
-Hook, um zwischen verschiedenen Themes (hell, dunkel usw.) zu wechseln. - Geolokalisierung: Erstellen Sie einen
useGeolocation
-Hook, um den aktuellen Standort des Benutzers zu verfolgen. - Scroll-Erkennung: Create a
useScroll
-Hook, um zu erkennen, wann der Benutzer zu einem bestimmten Punkt auf der Seite gescrollt hat.
Beispiel: useGeolocation-Hook für kulturübergreifende Anwendungen wie Kartierungs- oder Lieferdienste
import { useState, useEffect } from 'react';
function useGeolocation() {
const [location, setLocation] = useState({
latitude: null,
longitude: null,
error: null,
});
useEffect(() => {
if (!navigator.geolocation) {
setLocation({
latitude: null,
longitude: null,
error: 'Geolokalisierung wird von diesem Browser nicht unterstützt.',
});
return;
}
const watchId = navigator.geolocation.watchPosition(
(position) => {
setLocation({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null,
});
},
(error) => {
setLocation({
latitude: null,
longitude: null,
error: error.message,
});
}
);
return () => navigator.geolocation.clearWatch(watchId);
}, []);
return location;
}
export default useGeolocation;
Fazit
Custom Hooks sind ein leistungsstarkes Werkzeug, um saubereren, wiederverwendbareren und wartbareren React-Code zu schreiben. Indem Sie komplexe Logik in Custom Hooks kapseln, können Sie Ihre Komponenten vereinfachen, Codeduplizierung reduzieren und die Gesamtstruktur Ihrer Anwendungen verbessern. Machen Sie sich Custom Hooks zu eigen und erschließen Sie ihr Potenzial, um robustere und skalierbarere React-Anwendungen zu erstellen.
Beginnen Sie damit, Bereiche in Ihrer bestehenden Codebasis zu identifizieren, in denen Logik über mehrere Komponenten hinweg wiederholt wird. Refaktorisieren Sie diese Logik dann in Custom Hooks. Mit der Zeit werden Sie eine Bibliothek von wiederverwendbaren Hooks aufbauen, die Ihren Entwicklungsprozess beschleunigen und die Qualität Ihres Codes verbessern wird.
Denken Sie daran, Best Practices zu befolgen, häufige Fallstricke zu vermeiden und fortgeschrittene Muster zu erkunden, um das Beste aus Custom Hooks herauszuholen. Mit Übung und Erfahrung werden Sie zu einem Meister der Custom Hooks und einem effektiveren React-Entwickler.