Effekte im Griff

Wenn der Effekt bei jedem Tastendruck neu startet

Die Abhängigkeitsliste ist kein Formular, das man kleiner macht, bis Ruhe herrscht. Sie ist die Beschreibung dessen, worauf dein Effekt tatsächlich reagieren soll.

KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Seit 1997 am Markt Kleine Gruppen Präsenz und Live-Online Zertifizierte Trainer
Worum es geht

Eine gekürzte Abhängigkeitsliste tauscht eine Warnung gegen einen Fehler ein

Der Ablauf ist bekannt: Der Effekt läuft öfter als gedacht, die Warnung des Linters nennt einen Wert, der fehlt, jemand entfernt stattdessen den Wert aus der Liste oder schaltet die Regel für diese Zeile ab. Danach ist es still, und der Effekt arbeitet ab sofort mit Werten aus dem Durchlauf, in dem er zuletzt eingerichtet wurde. Bei einer Abfrage heißt das: Er holt Daten zum vorletzten Suchbegriff.

Diese Fehler sind besonders unangenehm, weil sie sich nicht als Absturz zeigen, sondern als seltsames Verhalten unter bestimmten Reihenfolgen. Zwei schnelle Klicks, und die alte Antwort überschreibt die neue. Ein Wechsel des Datensatzes, und die Detailansicht zeigt kurz die Daten des vorherigen. In der Entwicklung mit schnellem Netz passiert das nie, beim Kunden mit mobiler Verbindung ständig.

Der zweite große Anteil sind Effekte, die gar keine sein müssten. Ein Wert, der sich aus Zustand und Eigenschaften berechnen lässt, wird in einen zusätzlichen Zustand geschrieben und dort per Effekt nachgeführt. Das erzeugt einen zweiten Durchlauf, eine zweite Quelle für denselben Wert und die Gelegenheit, dass beide auseinanderlaufen.

KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Symptom, Ursache, Lösung

Fünf Beobachtungen aus dem Alltag

Alle fünf Fälle haben gemeinsam, dass die Fehlermeldung woanders auftaucht als die Ursache. Die Reihenfolge entspricht ungefähr der Häufigkeit, mit der sie in Projekten auftreten.

Symptom

Der Effekt läuft bei jedem Tastendruck, obwohl sich der eigentliche Suchbegriff gar nicht geändert hat.

Ursache

In der Abhängigkeitsliste steht ein Objekt oder eine Funktion, die im Durchlauf neu entsteht. Für den Vergleich ist das jedes Mal ein anderer Wert, unabhängig vom Inhalt.

Lösung

Nimm statt des Objekts die einzelnen Felder in die Liste auf, zieh Hilfsfunktionen in den Effekt hinein oder leg konstante Werte außerhalb der Komponente an. Erst wenn das nicht geht, wird die Funktion mit useCallback stabilisiert.

Symptom

Die Chat-Verbindung wird neu aufgebaut, sobald jemand das Farbschema umschaltet.

Ursache

Im Effekt steckt Logik, die nur nebenbei einen aktuellen Wert braucht, etwa für eine Benachrichtigung. Dieser Wert muss in die Liste, und damit reagiert der ganze Effekt darauf.

Lösung

Zieh den nicht reaktiven Teil in eine mit useEffectEvent erzeugte Funktion. Sie sieht immer die aktuellen Werte, gehört aber nicht in die Abhängigkeitsliste, sodass in der Liste nur noch die Kennung des Raums steht.

Symptom

Die Liste ist leer, die Warnung ist weg, und im Effekt stehen veraltete Werte.

Ursache

Der Effekt hat die Werte aus dem Durchlauf festgehalten, in dem er eingerichtet wurde. Alles, was danach kam, sieht er nicht.

Lösung

Trag die tatsächlich benutzten Werte ein und mach sie stabil. Wenn du in einem Zeitgeber oder einem Ereignisbehandler den jüngsten Zustand brauchst, nutz die Funktionsform von setState, die den vorherigen Wert übergeben bekommt.

Symptom

In der Entwicklung läuft der Effekt zweimal, im Produktionsbau einmal.

Ursache

Der strenge Modus hängt Effekte in der Entwicklung absichtlich aus und wieder ein. Sichtbar wird das nur bei Effekten, die nicht aufräumen.

Lösung

Schreib die Aufräumfunktion, statt den strengen Modus zu entfernen: Abonnement beenden, Zeitgeber löschen, Verbindung schließen, laufende Abfrage abbrechen. Danach ist das doppelte Einhängen ohne Wirkung.

Symptom

Zwei schnelle Wechsel, und die Ansicht zeigt die Daten des vorherigen Datensatzes.

Ursache

Zwei Abfragen laufen gleichzeitig, und die ältere kommt zuletzt an. Ohne Abbruch schreibt sie ihr Ergebnis über das neuere.

Lösung

Setz im Effekt eine Markierung, die die Aufräumfunktion umlegt, und ignorier das Ergebnis, wenn sie gesetzt ist, oder brich die Abfrage mit einem AbortController ab. Dauerhaft ist eine Abfragebibliothek die bessere Antwort, weil sie diesen Fall mitbringt.

Vier Fragen, bevor du einen Effekt schreibst

  1. 01 Lässt sich der Wert im Render berechnen? Dann brauchst du keinen Effekt.
  2. 02 Passiert es als Reaktion auf eine Bedienung? Dann gehört es in den Ereignisbehandler.
  3. 03 Synchronisierst du mit etwas außerhalb von React? Dann ist ein Effekt richtig.
  4. 04 Was muss beim Verlassen passieren? Diese Antwort ist die Aufräumfunktion.
  5. 05 Welcher Teil soll nicht neu starten? Der wandert in useEffectEvent.
Was du mitnimmst

Was du danach sicher unterscheidest

Fast alle Fälle lassen sich auf vier Fragen zurückführen: Muss das überhaupt ein Effekt sein, worauf soll er reagieren, was passiert beim Verlassen und welcher Teil des Effekts ist gar nicht reaktiv. Wer diese vier beantwortet, braucht die Regel nie abzuschalten.

Ableitung statt Effekt erkennen

Ein Wert, der sich aus vorhandenem Zustand ergibt, wird im Render berechnet und nicht in einem zusätzlichen Zustand gespiegelt. Das spart einen Durchlauf und beseitigt die Möglichkeit, dass beide Werte auseinanderlaufen.

Ereignisse von Effekten trennen

Was auf einen Klick hin passieren soll, gehört in den Klickbehandler. Ein Effekt gehört zur Synchronisierung mit etwas außerhalb von React, etwa einer Verbindung, einem Abonnement oder dem Dokumenttitel.

Abhängigkeiten stabil machen, nicht entfernen

Funktionen in den Effekt hineinziehen, konstante Werte außerhalb der Komponente anlegen, aus einem Objekt nur die benötigten Felder als Abhängigkeit nehmen. Die Liste beschreibt danach immer noch die Wahrheit.

Nicht reagierende Teile herauslösen

Mit useEffectEvent trennst du Logik ab, die zwar aktuelle Werte lesen soll, aber kein erneutes Ausführen auslösen darf. Diese Funktion gehört ausdrücklich nicht in die Abhängigkeitsliste. Verfügbar ist sie ab React 19.2; in älteren Projekten bleibt bis zum Upgrade nur, den nicht reaktiven Wert in einer Referenz zu halten und im Effekt daraus zu lesen.

Immer aufräumen

Jedes Abonnement, jeder Zeitgeber, jede offene Verbindung und jede laufende Abfrage braucht eine Aufräumfunktion. Sie läuft vor dem nächsten Durchlauf des Effekts und beim Aushängen, und sie ist der Grund, warum der strenge Modus in der Entwicklung doppelt einhängt.

Die Regeln der Hooks als Regeln lesen

Hooks werden über die Aufrufreihenfolge zugeordnet, deshalb dürfen sie nicht in Bedingungen, Schleifen oder nach einem vorzeitigen Verlassen der Funktion stehen. Das ist keine Stilfrage, sondern die Voraussetzung dafür, dass Zustand der richtigen Stelle zugeordnet wird.

KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt

Die Regeln der Hooks sind keine Stilfrage

React ordnet Zustand nicht über Namen zu, sondern über die Reihenfolge der Hook-Aufrufe innerhalb eines Durchlaufs. Deshalb müssen alle Hooks auf oberster Ebene der Komponente stehen: nicht in einer Bedingung, nicht in einer Schleife, nicht nach einem vorzeitigen return. Wird die Reihenfolge zwischen zwei Durchläufen unterschiedlich, bekommt ein Hook den Zustand eines anderen, und die Fehlermeldung spricht von einer abweichenden Anzahl gerenderter Hooks.

Aufrufbar sind Hooks außerdem nur in Komponenten und in eigenen Hooks. Ein eigener Hook ist dabei keine Sonderform, sondern eine normale Funktion, deren Name mit use beginnt und in der wieder Hooks vorkommen dürfen. Die Regeln gelten dort unverändert weiter, und genau das wird gern übersehen, wenn eine bedingte Logik aus der Komponente in einen eigenen Hook wandert.

Diese Regeln lassen sich prüfen. eslint-plugin-react-hooks meldet Verstöße und unvollständige Abhängigkeitslisten, und die empfohlene Zusammenstellung enthält inzwischen zusätzliche Regeln, die aus der Arbeit am React Compiler stammen, etwa gegen Zustandsänderungen während des Renderns oder in einem Effekt. Der Compiler selbst muss dafür nicht installiert sein.

Die meisten Effekte sind gar keine

Ein Effekt ist dafür da, deine Komponente mit etwas außerhalb von React abzugleichen: eine Verbindung, ein Abonnement, ein Zeitgeber, der Dokumenttitel, eine fremde Bibliothek, die auf ein DOM-Element zugreift. Alles andere gehört woandershin. Ein Wert, der sich aus Zustand und Eigenschaften ergibt, wird im Render berechnet, nicht in einen weiteren Zustand geschrieben und per Effekt nachgeführt.

Zwei Muster tauchen dabei besonders oft auf. Erstens die gefilterte Liste, die in einem eigenen Zustand liegt und über einen Effekt aktualisiert wird, obwohl sie sich in einer Zeile aus Daten und Suchbegriff berechnen lässt. Zweitens das Zurücksetzen von Zustand beim Wechsel eines Datensatzes, das häufig als Effekt geschrieben wird, obwohl ein passender key an der Komponente die Aufgabe vollständig übernimmt, weil React sie dann sauber neu aufbaut.

Ebenfalls kein Fall für einen Effekt sind Reaktionen auf Bedienung. Wenn nach dem Absenden eines Formulars eine Meldung erscheinen soll, gehört das in die Funktion, die das Absenden behandelt, und nicht in einen Effekt, der einen Zustand beobachtet. Der Unterschied ist nicht kosmetisch: Der Effekt läuft auch dann, wenn derselbe Zustand aus einem ganz anderen Grund entsteht.

Abhängigkeiten beruhigen, ohne zu lügen

Die Liste ist keine Einstellung, sondern eine Aussage: Diese Werte benutzt der Effekt, also muss er neu laufen, wenn sie sich ändern. Der richtige Ansatz ist deshalb, den Code so umzubauen, dass die Liste kurz wird, statt sie zu kürzen. Der einfachste Hebel: Alles, was nur der Effekt braucht, wandert in den Effekt hinein. Eine Funktion, die außerhalb steht und nur dort verwendet wird, gehört nach innen und verschwindet damit aus der Liste.

Bleibt ein Objekt übrig, das von außen kommt, nimm die einzelnen Felder als Abhängigkeit statt des Objekts. Aus einer Abhängigkeit vom ganzen Filterobjekt werden dann zwei Zeichenketten, die sich nur ändern, wenn sich wirklich etwas geändert hat. Konstante Werte, die nichts mit dem Zustand zu tun haben, gehören ganz aus der Komponente heraus in den Modulrumpf, dann stehen sie gar nicht mehr zur Debatte.

Seit React 19.2 gibt es für den verbleibenden Fall ein eigenes Mittel. useEffectEvent erzeugt eine Funktion, die immer die aktuellen Werte sieht, aber selbst keine erneute Ausführung auslöst und deshalb nicht in die Abhängigkeitsliste gehört. Das ist genau der Fall, in dem ein Effekt zwar mit einer Kennung synchronisiert, nebenbei aber eine Meldung mit dem aktuellen Farbschema oder dem angemeldeten Namen ausgibt. Wichtig ist die Abgrenzung: Das Mittel ist für ausdrücklich nicht reaktive Logik gedacht und nicht dafür, eine unbequeme Warnung stillzulegen.

Aufräumen gehört zum Effekt

Die Rückgabe eines Effekts ist die Aufräumfunktion. React ruft sie vor dem nächsten Durchlauf des Effekts auf und ein letztes Mal beim Aushängen der Komponente. Gedanklich sauber wird ein Effekt, wenn du ihn als Paar liest: Was wird eingerichtet, und wie wird es wieder abgebaut. Eine Verbindung wird geöffnet und geschlossen, ein Zuhörer angemeldet und abgemeldet, ein Zeitgeber gesetzt und gelöscht.

Der strenge Modus in der Entwicklung führt genau diesen Zyklus einmal zusätzlich aus. Das ist kein Fehler, sondern eine Prüfung: Ein Effekt, der ohne Aufräumfunktion auskommt, fällt hier sofort auf, etwa weil zwei Verbindungen offen sind oder ein Ereignis doppelt gezählt wird. Die richtige Antwort ist die fehlende Aufräumfunktion, nicht das Abschalten des Modus.

Beim Datenholen im Effekt gehört zusätzlich der Abbruch dazu. Entweder setzt du in der Aufräumfunktion eine Markierung, die das Ergebnis der alten Abfrage verwirft, oder du brichst sie über einen AbortController ab. Beides verhindert, dass eine langsamere ältere Antwort eine neuere überschreibt. Wenn dieses Muster an mehreren Stellen auftaucht, ist es das deutlichste Zeichen dafür, dass eine Abfragebibliothek die passendere Lösung wäre.

Eigene Hooks setzen die Regeln nicht außer Kraft

Ein eigener Hook bündelt Zustand und Effekte hinter einem Namen. Das ist die richtige Antwort, wenn dieselbe Kombination an mehreren Stellen gebraucht wird, etwa das Abonnieren einer Datenquelle samt Abmeldung. Der Hook erbt dabei alle Regeln: Aufrufe auf oberster Ebene, keine Bedingungen, und die Abhängigkeitslisten darin sind genauso ernst zu nehmen wie in der Komponente.

Zwei Punkte entscheiden über die Qualität eines eigenen Hooks. Erstens die Rückgabe: Wenn sie ein Objekt ist, das bei jedem Durchlauf neu entsteht, vererbt der Hook seine Instabilität an jede Komponente, die ihn benutzt, und deren Effekte laufen dann zu oft. Zweitens der Zuschnitt: Ein Hook, der drei unabhängige Dinge erledigt, zwingt jede aufrufende Stelle dazu, alle drei zu bekommen.

Für den Zugriff auf Datenquellen außerhalb von React gibt es mit useSyncExternalStore ein eigenes Mittel. Es meldet sich an der Quelle an, liest den aktuellen Wert und sorgt dafür, dass React beim Rendern nichts Veraltetes sieht. Das ist der saubere Weg für Browserwerte wie die Fensterbreite, den Online-Zustand oder einen externen Speicher, und er kommt ohne den üblichen Umweg über useState mit einem Effekt aus.

Dazu passende Kurse

Wer bei cmt eigenen Code mitbringt, findet darin fast immer Effekte, die gar keine sein müssten .

Veraltete Werte in einem Effekt sind kein React-Thema, sondern ein Abschluss über alte Variablen, deshalb hilft es, Abschlüsse und Referenzen in JavaScript verstehen .

Wissen prüfen

Wie sicher bist du beim Thema wirklich?

Lesen fühlt sich schnell nach Können an. Ein kurzer Test zeigt dir, was davon schon sitzt und wo sich ein Kurs lohnt. Kostenlos, ohne Anmeldung, mit einer Erklärung zu jeder Antwort.

Der passende Lernpfad

Wenn du nicht nur ein Thema abhaken, sondern eine Rolle ausfüllen willst, zeigt dir der Lernpfad die Kurse in der Reihenfolge, in der sie aufeinander aufbauen.

Karrierepfad

Dein Weg zum React Entwickler

Moderne Web-Produkte werden heute mit React gebaut. Wer es sauber beherrscht, arbeitet an echten Web-Anwendungen – nicht an Spielwiesen.
 

Dieser Karrierepfad führt dich gezielt von den Grundlagen über Architektur und Design bis hin zu professionellen React-Frontends, wie sie in produktiven Teams erwartet werden. Starte einfach durch!

Ein sehr gutes, praxisorientiertes und nachhaltiges Seminar. So sollte es immer sein. Vielen Dank.
LimeSurvey - Anwendertraining Teil 1 (Grundlagen)
Die Schulung ist gerade für Einsteiger oder Entwickler*innen mit eingestaubtem Basiswissen sehr hilfreich.
Vue.js 3 Grundkurs
Ich bin sehr glücklich Franz als Trainer gehabt zu haben. Er hat offensichtlich unglaublich viel Wissen zu den Themen, und schafft es, dieses auch interaktiv und verständlich weiterzugeben.
React Komplettausbildung

Häufige Fragen

Darf ich die Regel für die Abhängigkeitsliste in einer Zeile abschalten?
Praktisch nie, und wenn doch, gehört ein Kommentar daneben, der erklärt, welcher Wert absichtlich fehlt und warum das sicher ist. In fast allen Fällen gibt es einen sauberen Weg: den Wert stabil machen, ihn in den Effekt ziehen oder den nicht reaktiven Teil mit useEffectEvent herauslösen.
Wie hole ich Daten in einem Effekt richtig?
Mit Abbruch. Setz eine Markierung, die die Aufräumfunktion umlegt, und ignorier das Ergebnis, wenn sie gesetzt ist, oder brich die Anfrage über einen AbortController ab. Zusätzlich brauchst du Lade- und Fehlerzustand. Sobald das an mehreren Stellen steht, ist eine Bibliothek für Serverdaten der bessere Weg, weil sie Abbruch, Wiederholung und Zwischenspeicher mitbringt.
Wann ist useEffectEvent das richtige Mittel?
Wenn ein Effekt aktuelle Werte lesen soll, ohne auf ihre Änderung zu reagieren. Das klassische Beispiel ist eine Verbindung, die nur von einer Kennung abhängt, beim Verbinden aber eine Meldung mit dem aktuellen Farbschema anzeigt. Die so erzeugte Funktion gehört nicht in die Abhängigkeitsliste und darf nur innerhalb der Komponente oder des Hooks verwendet werden, in dem sie deklariert wurde. Zur Verfügung steht sie seit React 19.2, davor löst man denselben Fall über eine Referenz, die den aktuellen Wert hält.
Warum bekomme ich die Meldung über eine abweichende Anzahl von Hooks?
Weil zwischen zwei Durchläufen unterschiedlich viele Hooks aufgerufen wurden. Meistens steht ein Hook hinter einer Bedingung oder nach einem vorzeitigen return, oder eine Schleife über Daten ruft Hooks auf. Die Lösung ist, die Bedingung nach innen zu verlagern: Der Hook wird immer aufgerufen, und erst in seinem Inneren wird entschieden, ob er etwas tut.
Persönlich für dich da

Deine Ansprechpartner

Du bist dir nicht sicher, welcher Kurs oder welches Level zu dir passt? Wir beraten dich persönlich und kostenlos.

Yves Hoppe

Yves Hoppe

Weiterbildung & Beratung

Hilft dir, aus dem Webentwicklung-Programm den passenden Kurs für deinen Stand zu finden.

Norbert Jansen

Norbert Jansen

Beratung & Inhouse

Plant mit dir Inhouse-Trainings, die auf eure Abläufe und euren Datenbestand zugeschnitten sind.

Effekte, die genau dann laufen, wenn sie sollen

Bei cmt gehst du diese Fälle an eigenem Code durch, von der zu langen Abhängigkeitsliste bis zum Abbruch der überholten Abfrage.