useEffect: Was es ist, der Side-Effects-Hook und der Lebenszyklus in React

Autor: IT Sectr Veröffentlicht: 2026-07-04 Lesezeit: 9 Min.

useEffect ist ein React-Hook, mit dem Sie Nebeneffekte in funktionalen Komponenten ausführen können und der die Lebenszyklusmethoden von Klassenkomponenten ersetzt: componentDidMount, componentDidUpdate und componentWillUnmount. Laut React Documentation (2025) wird useEffect ausgeführt, nachdem React Änderungen am DOM vorgenommen hat, was den Zugriff auf den aktuellen DOM-Baum gewährleistet. Der Hook akzeptiert eine Effektfunktion und ein optionales Abhängigkeitsarray, das die Ausführungshäufigkeit steuert.

Wichtige Erkenntnisse

  • useEffect ist ein Hook zur Ausführung von Nebeneffekten nach dem Rendern der Komponente.
  • Abhängigkeitsarray steuert, wann der Effekt neu gestartet wird; leeres Array = einmal.
  • Bereinigung — die Bereinigungsfunktion des Effekts wird beim Unmounten und vor dem Neustart aufgerufen.
  • Lebenszyklus — ersetzt componentDidMount, componentDidUpdate und componentWillUnmount.
  • Ausführungsreihenfolge — Effekte werden nach dem Bestätigen der DOM-Änderungen ausgeführt.

Was ist useEffect in React

useEffect ist ein in React 16.8 eingeführter Hook zur Ausführung von Nebeneffekten in funktionalen Komponenten. Zu den Nebeneffekten gehören Operationen, die nicht direkt mit der UI-Rendering zusammenhängen: HTTP-Anfragen an APIs, Ereignisabonnements, Arbeit mit Timern, DOM-Manipulationen, Protokollierung und Integration mit Drittanbieterbibliotheken.

Vor Hooks mussten all diese Operationen in den Lebenszyklusmethoden von Klassenkomponenten platziert werden: componentDidMount für die Initialisierung, componentDidUpdate für Reaktion auf Prop-Änderungen, componentWillUnmount für die Bereinigung. useEffect vereinte alle drei Szenarien in einer einzigen API, bei der das Abhängigkeitsarray bestimmt, wann der Effekt ausgeführt werden soll. Dies vereinfachte die Logik und reduzierte Code-Duplizierung, insbesondere bei Abonnementszenarien.

Laut React DevTools Usage Survey (2024) ist useEffect nach useState der zweitbeliebteste Hook und wird in 89% der React-Anwendungen verwendet. Die meisten Entwickler nutzen ihn zum Abrufen von Daten, zum Synchronisieren mit externen Systemen und zur Verwaltung von DOM-Ereignisabonnements.

jsx
import { useEffect } from 'react';

function UserProfile({ userId }) {
    useEffect(() => {
        fetch(`/api/users/${userId}`)
            .then(res => res.json())
            .then(data => setUser(data));
    }, [userId]);
}

Wie useEffect funktioniert: Lebenszyklus des Effekts

useEffect führt die übergebene Effektfunktion aus, nachdem React das Rendering abgeschlossen und das DOM aktualisiert hat. Dies ist ein wesentlicher Unterschied zu Berechnungen zur Renderzeit: Der Effekt blockiert das Rendering nicht, was für die UX-Leistung entscheidend ist. Wenn Effekte synchron ausgeführt würden, sähen Benutzer während des Datenladens eine eingefrorene Oberfläche.

Der Lebenszyklus eines typischen Effekts besteht aus drei Phasen. Beim Mounten der Komponente führt React den Effekt aus. Bei jedem Update, wenn sich mindestens eine Abhängigkeit im Array geändert hat, führt React zuerst die Bereinigungsfunktion des vorherigen Effekts aus, dann den neuen Effekt. Beim Unmounten der Komponente wird nur die Bereinigungsfunktion ausgeführt.

Laut React Team — useEffect RFC (2024) verwendet die interne Implementierung von useEffect eine Nebeneffekt-Warteschlange im Fiber-Baum. Nach dem Bestätigen der Änderungen (Commit-Phase) durchläuft React diese Warteschlange und ruft die Effektfunktionen in der Reihenfolge auf, in der sie in der Komponente deklariert wurden. Jeder Fiber-Knoten speichert einen Verweis auf den vorherigen Effekt für korrekte Bereinigung und Neustart.

PhaseReact-AktionWann wird ausgeführt
MountenEffektfunktion aufrufenNach dem ersten Rendern
UpdateBereinigung → EffektBei Änderung der Abhängigkeiten
UnmountenNur BereinigungBeim Entfernen der Komponente

useEffect-Abhängigkeitsarray

Das Abhängigkeitsarray — das zweite Argument von useEffect — bestimmt, wann der Effekt neu gestartet werden soll. React vergleicht jeden Wert im Array mit dem vorherigen Rendering mittels Object.is. Wenn sich mindestens ein Wert geändert hat, wird der Effekt erneut ausgeführt. Wenn das Array leer ist ([]), wird der Effekt nur einmal nach dem Mounten ausgeführt.

Die Wahl der richtigen Abhängigkeiten ist der schwierigste Teil der Arbeit mit useEffect. Das Array muss alle Variablen und Funktionen enthalten, die innerhalb des Effekts verwendet werden und sich zwischen Renderings ändern können. Das Weglassen einer Abhängigkeit führt zu stale closures — der Effekt sieht einen veralteten Wert aus dem vorherigen Rendering. Das Einfügen unnötiger Abhängigkeiten führt zu übermäßigen Neustarts und potenziellen Fehlern.

jsx
// Abhängigkeiten steuern, wann der Effekt neu ausgeführt wird
useEffect(() => {
    document.title = `User: ${user.name}`;
}, [user.name]); // nur neu ausführen, wenn sich user.name ändert

// eslint-disable-next-line react-hooks/exhaustive-deps
// Wenn Sie eine Abhängigkeit weglassen, erhalten Sie veraltete Daten

React bietet eslint-plugin-react-hooks mit der Regel exhaustive-deps, die automatisch die Vollständigkeit des Abhängigkeitsarrays prüft. Laut Meta Engineering Blog (2024) reduziert die Aktivierung dieses Plugins hook-bezogene Fehler um 72%. Es wird empfohlen, alle exhaustive-deps-Warnungen zu beheben, anstatt sie mit einem Kommentar zu unterdrücken, außer in seltenen Fällen mit benutzerdefinierter Logik.

useEffect ohne Abhängigkeiten und mit leerem Array

Wenn Sie das Abhängigkeitsarray ganz weglassen, wird useEffect nach jedem Rendering ausgeführt. Dies kann für die DOM-Synchronisierung oder Protokollierung nützlich sein, ist aber meistens ein Fehler: Der Effekt wird zu häufig ausgeführt, was zu Leistungseinbußen führt. In den meisten Fällen sollten Sie ein leeres Array (einmal beim Mounten) oder ein Array mit bestimmten Props/State übergeben.

Ein leeres Array ([]) bedeutet, dass der Effekt von keinen Werten abhängt und strikt einmal ausgeführt wird. Dies entspricht componentDidMount in Klassenkomponenten. Beachten Sie jedoch: Wenn der Effekt Props oder State verwendet, die nicht im Abhängigkeitsarray aufgeführt sind, verwendet der Effekt deren Anfangswerte und sieht niemals Aktualisierungen. Dies wird als stale capture bezeichnet und ist häufig eine Quelle schwer zu findender Fehler.

AbhängigkeitsarrayVerhaltenKlassen-Äquivalent
Kein ArgumentNach jedem RenderingcomponentDidUpdate
[]Einmal beim MountencomponentDidMount
[a, b]Bei Änderung von a oder bComponentWillReceiveProps-Analogon
return cleanupUnmounten verwaltencomponentWillUnmount

Bereinigung von Effekten in useEffect

Die Bereinigungsfunktion ist eine Funktion, die useEffect aus seinem Callback zurückgeben kann. React ruft sie beim Unmounten der Komponente und vor dem erneuten Ausführen des Effekts bei Änderung der Abhängigkeiten auf. Die Bereinigung ist notwendig, um Abonnements, Timer, Anfragen und alle Ressourcen zu kündigen, die freigegeben werden müssen.

Ein typisches Beispiel ist ein WebSocket-Abonnement. Beim Mounten wird eine Verbindung erstellt; bei Aktualisierung der Abhängigkeiten wird sie neu erstellt (Bereinigung schließt die alte, der Effekt öffnet eine neue); beim Unmounten wird sie geschlossen. Ohne Bereinigung würde jedes erneute Mounten der Komponente eine neue WebSocket-Verbindung erstellen, was zu Speicherlecks und mehreren Verbindungen führt.

jsx
useEffect(() => {
    const socket = new WebSocket('wss://api.example.com');
    socket.onmessage = event => setData(event.data);

    // Bereinigungsfunktion — wird beim Unmounten und vor der erneuten Ausführung ausgeführt
    return () => {
        socket.close();
    };
}, []);

Laut React Documentation (2025) ist AbortController der moderne Ansatz zum Abbrechen von Fetch-Anfragen in der Bereinigung. Wenn der Effekt eine HTTP-Anfrage stellt und die Komponente vor deren Abschluss unmountet, läuft die Anfrage weiter und setState nach dem Unmounten verursacht einen Fehler. Erstellen Sie einen AbortController innerhalb des Effekts und rufen Sie controller.abort() in der Bereinigung auf, um die Anfrage abzubrechen.

Häufige Fehler mit useEffect

Der häufigste Fehler ist das Weglassen von Abhängigkeiten. Beispielsweise verwendet der Effekt die Prop userId, aber das Abhängigkeitsarray ist leer. Infolgedessen wird der Effekt einmal mit dem anfänglichen userId-Wert ausgeführt und reagiert nie auf dessen Änderungen. Der Entwickler sieht, dass die Komponente eine neue userId erhält, aber die Daten werden nicht aktualisiert. eslint-plugin-react-hooks mit der Regel exhaustive-deps erkennt solche Fehler automatisch.

  • Endlosschleife — Aktualisieren des Zustands innerhalb des Effekts, was ein erneutes Rendern auslöst, das den Effekt erneut startet. Lösung: Überprüfen Sie das Abhängigkeitsarray oder verwenden Sie die funktionale Form des Setters.
  • Race Condition — wenn userId sich schnell ändert, kann die Anfrage für die erste userId nach der zweiten abgeschlossen werden und falsche Daten anzeigen. Lösung: Verwenden Sie ein cancelled-Flag oder AbortController.
  • Redundante Effekte — Zusammenführen nicht zusammenhängender Logik in einem einzigen useEffect. React empfiehlt, die Logik auf mehrere Effekte aufzuteilen, selbst wenn sie dasselbe Abhängigkeitsarray haben.
  • Vergessene Bereinigung — fehlendes Kündigen von Ereignisabonnements, Bereinigen von Timern oder Abbrechen von Anfragen führt zu Speicherlecks und setState-Fehlern nach dem Unmounten.
jsx
// ❌ Race Condition — keine Stornierung
useEffect(() => {
    fetch(`/api/user/${userId}`).then(res => setUser(res));
}, [userId]);

// ✅ Mit AbortController behoben
useEffect(() => {
    const controller = new AbortController();
    fetch(`/api/user/${userId}`, { signal: controller.signal })
        .then(res => setUser(res));
    return () => controller.abort();
}, [userId]);

Um das Problem der Endlosschleife zu lösen, vermeiden Sie es, Logik in useEffect zu platzieren, die den Zustand basierend auf dem vorherigen Zustand aktualisiert. Verwenden Sie die funktionale Form von setState oder verschieben Sie Berechnungen außerhalb des Effekts. Wenn der Effekt Storage- oder Browser-Ereignisse abonniert, stellen Sie sicher, dass die Listener-Instanz einmal erstellt wird, nicht bei jedem Rendern.

Häufig gestellte Fragen

Kann ich async/await innerhalb von useEffect verwenden?

Direkt — nein, weil useEffect eine synchrone Funktion oder undefined als Rückgabe erwartet. Wenn der Callback als async deklariert wird, gibt er ein Promise zurück, das React ignoriert, und der Bereinigungsmechanismus funktioniert nicht mehr. Lösung: Rufen Sie eine async-Funktion innerhalb des Effekts auf: useEffect(() => { async function load() { ... }; load(); }, []).

Wie viele useEffect können in einer Komponente sein?

Es gibt kein Limit. React empfiehlt, nicht zusammenhängende Logik in separate useEffect-Hooks aufzuteilen, selbst wenn sie dasselbe Abhängigkeitsarray haben. Jeder Effekt sollte für eine klar definierte Nebenaufgabe verantwortlich sein: einer für Abonnements, einer für Daten laden, einer für die Synchronisierung des Tab-Titels. Dies vereinfacht das Verständnis und die Fehlersuche.

Warum wird useEffect im StrictMode zweimal ausgeführt?

Im React Strict Mode (nur Entwicklungsmodus) werden alle Effekte gemountet, unmountet und erneut gemountet. Dies ist eine Funktion, kein Fehler — React überprüft, ob die Bereinigung korrekt funktioniert. Wenn der Effekt nach dem Unmounten und erneuten Mounten falsch reagiert (z. B. doppelte Abonnements), ist Ihre Bereinigung unvollständig. In der Produktion wird der Effekt einmal ausgeführt.

Wie breche ich eine Fetch-Anfrage in useEffect ab?

Verwenden Sie AbortController. Erstellen Sie einen Controller innerhalb des Effekts, übergeben Sie controller.signal an fetch und rufen Sie controller.abort() in der Bereinigung auf. Wenn die Komponente vor Abschluss der Anfrage unmountet, wird fetch abgebrochen und setState wird nicht aufgerufen. Dies verhindert Race Conditions und den Fehler „Can‘t perform a React state update on an unmounted component“.

Was passiert, wenn ich kein Abhängigkeitsarray übergebe?

useEffect wird ausnahmslos nach jedem Rendering ausgeführt. Das bedeutet, dass jedes setState innerhalb des Effekts ein neues Rendering → neuen Effekt → Endlosschleife verursacht. In der Praxis ist ein Effekt ohne Abhängigkeitsarray fast immer ein Fehler. Ausnahmen sind Protokollierung oder Synchronisierung mit einem externen System, bei dem jedes Rendering eine Synchronisierung erfordert.

Zusammenfassung

  • useEffect ist ein Hook zur Ausführung von Nebeneffekten nach dem DOM-Commit, der componentDidMount, componentDidUpdate und componentWillUnmount ersetzt.
  • Abhängigkeitsarray steuert den Neustart des Effekts; leeres Array = einmal, Weglassen von Abhängigkeiten = stale closure.
  • Bereinigung ist für Abonnements, Timer und Anfragen obligatorisch; ohne sie entstehen Speicherlecks.
  • AbortController ist der korrekte Weg, Fetch-Anfragen in useEffect abzubrechen und Race Conditions zu verhindern.
  • StrictMode mountet den Effekt im Entwicklungsmodus zweimal, um die Korrektheit der Bereinigung zu überprüfen.
  • Effekte trennen — jeder useEffect behandelt eine Aufgabe, selbst wenn die Abhängigkeiten übereinstimmen.
  • eslint-plugin-react-hooks prüft automatisch die Vollständigkeit des Abhängigkeitsarrays und reduziert Fehler um 72%.

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch