v19.2Latest

Entfernen von Effect-Abhängigkeiten

Wenn Sie einen Effect schreiben, überprüft der Linter, dass Sie jeden reaktiven Wert (wie Props und State), den der Effect liest, in die Liste der Abhängigkeiten Ihres Effects aufgenommen haben. Dies stellt sicher, dass Ihr Effect mit den neuesten Props und dem State Ihrer Komponente synchron bleibt. Unnötige Abhängigkeiten können dazu führen, dass Ihr Effect zu oft ausgeführt wird oder sogar eine Endlosschleife erzeugt. Befolgen Sie diese Anleitung, um unnötige Abhängigkeiten in Ihren Effects zu überprüfen und zu entfernen.

Sie werden lernen
  • Wie man Endlosschleifen bei Effect-Abhängigkeiten behebt
  • Was zu tun ist, wenn Sie eine Abhängigkeit entfernen möchten
  • Wie man einen Wert aus Ihrem Effect liest, ohne darauf zu „reagieren“
  • Wie und warum man Objekt- und Funktionsabhängigkeiten vermeidet
  • Warum das Unterdrücken des Abhängigkeits-Linters gefährlich ist und was stattdessen zu tun ist

Abhängigkeiten sollten mit dem Code übereinstimmen

Wenn Sie einen Effect schreiben, geben Sie zunächst an, wie Siestarten und stoppenmöchten, was Ihr Effect tun soll:

Wenn Sie dann die Effect-Abhängigkeiten leer lassen ([]), schlägt der Linter die korrekten Abhängigkeiten vor:

Füllen Sie sie gemäß den Angaben des Linters aus:

Effects „reagieren“ auf reaktive Werte. Da roomIdein reaktiver Wert ist (er kann sich durch ein erneutes Rendern ändern), überprüft der Linter, dass Sie ihn als Abhängigkeit angegeben haben. WennroomIdeinen anderen Wert erhält, synchronisiert React Ihren Effect neu. Dies stellt sicher, dass der Chat mit dem ausgewählten Raum verbunden bleibt und auf die Dropdown-Auswahl „reagiert“:

Um eine Abhängigkeit zu entfernen, beweise, dass sie keine Abhängigkeit ist

Beachte, dass du die Abhängigkeiten deines Effects nicht „auswählen“ kannst. Jederreaktive Wert, der im Code deines Effects verwendet wird, muss in deiner Abhängigkeitsliste deklariert werden. Die Abhängigkeitsliste wird durch den umgebenden Code bestimmt:

Reaktive Werteumfassen Props und alle Variablen und Funktionen, die direkt innerhalb deiner Komponente deklariert sind. DaroomIdein reaktiver Wert ist, kannst du ihn nicht aus der Abhängigkeitsliste entfernen. Der Linter würde es nicht erlauben:

Und der Linter hätte recht! Da sichroomIdim Laufe der Zeit ändern kann, würde dies einen Bug in deinem Code einführen.

Um eine Abhängigkeit zu entfernen, „beweise“ dem Linter, dass siekeineAbhängigkeit sein muss.Du kannst zum BeispielroomIdaus deiner Komponente herausbewegen, um zu beweisen, dass es nicht reaktiv ist und sich bei erneuten Render-Vorgängen nicht ändert:

Da roomIdnun kein reaktiver Wert mehr ist (und sich bei einem erneuten Rendering nicht ändern kann), muss es keine Abhängigkeit sein:

Deshalb können Sie jetzt eineleere ([]) Abhängigkeitsliste angeben.Ihr Effect hängtwirklich nicht mehrvon einem reaktiven Wert ab, daher muss erwirklich nichterneut ausgeführt werden, wenn sich die Props oder der State der Komponente ändern.

Um die Abhängigkeiten zu ändern, ändern Sie den Code

Vielleicht ist Ihnen in Ihrem Arbeitsablauf ein Muster aufgefallen:

  1. Zuerständern Sie den CodeIhres Effects oder wie Ihre reaktiven Werte deklariert sind.
  2. Dann folgen Sie dem Linter und passen die Abhängigkeiten an, ummit dem geänderten Code übereinzustimmen.
  3. Wenn Sie mit der Abhängigkeitsliste nicht zufrieden sind,gehen Sie zurück zum ersten Schritt(und ändern den Code erneut).

Der letzte Teil ist wichtig.Wenn Sie die Abhängigkeiten ändern möchten, ändern Sie zuerst den umgebenden Code.Sie können sich die Abhängigkeitsliste alseine Liste aller reaktiven Werte vorstellen, die vom Code Ihres Effects verwendet werden. Sie wählen nicht aus, was auf diese Liste kommt. Die ListebeschreibtIhren Code. Um die Abhängigkeitsliste zu ändern, ändern Sie den Code.

Das kann sich anfühlen, als würde man eine Gleichung lösen. Vielleicht beginnen Sie mit einem Ziel (zum Beispiel, eine Abhängigkeit zu entfernen) und müssen den dazu passenden Code „finden“. Nicht jeder findet es spaßig, Gleichungen zu lösen, und dasselbe könnte man über das Schreiben von Effects sagen! Glücklicherweise gibt es unten eine Liste gängiger Rezepte, die Sie ausprobieren können.

Fallstrick

Wenn Sie einen bestehenden Codebase haben, könnten Sie einige Effects haben, die den Linter wie folgt unterdrücken:

Wenn die Abhängigkeiten nicht mit dem Code übereinstimmen, besteht ein sehr hohes Risiko, Fehler einzuführen.Indem Sie den Linter unterdrücken, „lügen“ Sie React über die Werte, von denen Ihr Effect abhängt.

Verwenden Sie stattdessen die untenstehenden Techniken.

Unnötige Abhängigkeiten entfernen

Jedes Mal, wenn Sie die Abhängigkeiten des Effects anpassen, um den Code widerzuspiegeln, sehen Sie sich die Abhängigkeitsliste an. Ist es sinnvoll, dass der Effect erneut ausgeführt wird, wenn sich eine dieser Abhängigkeiten ändert? Manchmal lautet die Antwort „nein“:

  • Möglicherweise möchten Sieverschiedene TeileIhres Effekts unter verschiedenen Bedingungen erneut ausführen.
  • Möglicherweise möchten Sie nur denaktuellsten Werteiner Abhängigkeit lesen, anstatt auf seine Änderungen zu „reagieren“.
  • Eine Abhängigkeit kann sich möglicherweise zu oftunbeabsichtigtändern, weil es sich um ein Objekt oder eine Funktion handelt.

Um die richtige Lösung zu finden, müssen Sie einige Fragen zu Ihrem Effekt beantworten. Gehen wir sie gemeinsam durch.

Sollte dieser Code in einen Event-Handler verschoben werden?

Das Erste, worüber Sie nachdenken sollten, ist, ob dieser Code überhaupt ein Effekt sein sollte.

Stellen Sie sich ein Formular vor. Beim Absenden setzen Sie die Zustandsvariablesubmitted auf true. Sie müssen eine POST-Anfrage senden und eine Benachrichtigung anzeigen. Sie haben diese Logik in einen Effekt gepackt, der aufsubmittedgleichtrue„reagiert“:

Später möchten Sie die Benachrichtigungsnachricht gemäß dem aktuellen Theme stylen, also lesen Sie das aktuelle Theme. Dathemeim Komponentenkörper deklariert ist, handelt es sich um einen reaktiven Wert, daher fügen Sie ihn als Abhängigkeit hinzu:

Dadurch haben Sie einen Bug eingeführt. Stellen Sie sich vor, Sie senden das Formular zuerst ab und wechseln dann zwischen Dark- und Light-Themes. Dasthemeändert sich, der Effekt wird erneut ausgeführt und zeigt dieselbe Benachrichtigung erneut an!

Das Problem hier ist, dass dies überhaupt kein Effekt sein sollte.Sie möchten diese POST-Anfrage senden und die Benachrichtigung als Reaktion auf dasAbsenden des Formularsanzeigen, was eine bestimmte Interaktion ist. Um Code als Reaktion auf eine bestimmte Interaktion auszuführen, platzieren Sie diese Logik direkt im entsprechenden Event-Handler:

Da der Code jetzt in einem Event-Handler ist, ist er nicht reaktiv – er wird also nur ausgeführt, wenn der Benutzer das Formular absendet. Lesen Sie mehr überdie Wahl zwischen Event-Handlern und Effektenundwie Sie unnötige Effekte entfernen.

Führt Ihr Effekt mehrere unabhängige Dinge aus?

Die nächste Frage, die Sie sich stellen sollten, ist, ob Ihr Effekt mehrere unabhängige Dinge tut.

Stellen Sie sich vor, Sie erstellen ein Versandformular, bei dem der Benutzer seine Stadt und Region auswählen muss. Sie holen die Liste dercitiesvom Server gemäß dem ausgewähltencountryab, um sie in einem Dropdown-Menü anzuzeigen:

Dies ist ein gutes Beispiel für dasAbrufen von Daten in einem Effekt.Sie synchronisieren dencities-Zustand mit dem Netzwerk gemäß dercountry-Prop. Das können Sie nicht in einem Event-Handler tun, weil Sie die Daten abrufen müssen, sobaldShippingFormangezeigt wird und wann immer sich diecountryändert (unabhängig davon, welche Interaktion dies verursacht).

Nehmen wir nun an, Sie fügen eine zweite Auswahlbox für Stadtbezirke hinzu, die dieareasfür die aktuell ausgewähltecityabrufen soll. Sie könnten damit beginnen, einen zweitenfetch-Aufruf für die Liste der Bezirke innerhalb desselben Effekts hinzuzufügen:

Da der Effekt jedoch nun die Zustandsvariablecityverwendet, mussten Siecityzur Liste der Abhängigkeiten hinzufügen. Das wiederum hat ein Problem verursacht: Wenn der Benutzer eine andere Stadt auswählt, wird der Effekt erneut ausgeführt undfetchCities(country)aufgerufen. Dadurch wird die Liste der Städte unnötig oft neu abgerufen.

Das Problem mit diesem Code ist, dass Sie zwei verschiedene, unabhängige Dinge synchronisieren:

  1. Sie möchten den Zustandcitiesbasierend auf der Propcountrymit dem Netzwerk synchronisieren.
  2. Sie möchten den Zustandareasbasierend auf dem Zustandcitymit dem Netzwerk synchronisieren.

Teilen Sie die Logik in zwei Effekte auf, von denen jeder auf die Prop reagiert, mit der er synchronisiert werden muss:

Jetzt wird der erste Effekt nur neu ausgeführt, wenn sichcountryändert, während der zweite Effekt neu ausgeführt wird, wenn sichcityändert. Sie haben sie nach ihrem Zweck getrennt: Zwei verschiedene Dinge werden durch zwei separate Effekte synchronisiert. Zwei separate Effekte haben zwei separate Abhängigkeitslisten, sodass sie sich nicht unbeabsichtigt gegenseitig auslösen.

Der endgültige Code ist länger als der ursprüngliche, aber das Aufteilen dieser Effekte ist dennoch korrekt.Jeder Effekt sollte einen unabhängigen Synchronisationsprozess darstellen.In diesem Beispiel bricht das Löschen eines Effekts nicht die Logik des anderen Effekts. Das bedeutet, siesynchronisieren verschiedene Dinge,und es ist gut, sie aufzuteilen. Wenn Sie sich über Duplizierung sorgen, können Sie diesen Code verbessern, indem Siewiederkehrende Logik in einen benutzerdefinierten Hook auslagern.

Lesen Sie einen Zustand, um den nächsten Zustand zu berechnen?

Dieser Effekt aktualisiert die Zustandsvariablemessagesjedes Mal, wenn eine neue Nachricht eintrifft, mit einem neu erstellten Array:

Er verwendet die Variablemessages, umein neues Array zu erstellen, das mit allen vorhandenen Nachrichten beginnt und die neue Nachricht am Ende hinzufügt. Da jedochmessagesein reaktiver Wert ist, der von einem Effekt gelesen wird, muss er eine Abhängigkeit sein:

Und messagesals Abhängigkeit zu machen, führt zu einem Problem.

Jedes Mal, wenn Sie eine Nachricht erhalten, bewirktsetMessages(), dass die Komponente mit einem neuenmessages-Array, das die empfangene Nachricht enthält, neu gerendert wird. Da dieser Effekt jedoch nun vonmessagesabhängt, wird diesauchden Effekt erneut synchronisieren. Also wird jede neue Nachricht den Chat neu verbinden. Das würde dem Benutzer nicht gefallen!

Um das Problem zu beheben, lesen Siemessagesnicht innerhalb des Effekts. Übergeben Sie stattdessen eineUpdater-FunktionansetMessages:

Beachten Sie, dass Ihr Effekt die Variablemessagesjetzt überhaupt nicht mehr liest.Sie müssen nur eine Updater-Funktion wiemsgs => [...msgs, receivedMessage]übergeben. Reactstellt Ihre Updater-Funktion in eine Warteschlangeund wird das Argumentmsgswährend des nächsten Renders bereitstellen. Deshalb muss der Effekt selbst nicht mehr vonmessagesabhängen. Durch diese Korrektur führt das Empfangen einer Chat-Nachricht nicht mehr dazu, dass der Chat sich erneut verbindet.

Möchten Sie einen Wert lesen, ohne auf seine Änderungen zu „reagieren“?

Angenommen, Sie möchten einen Sound abspielen, wenn der Benutzer eine neue Nachricht erhält, es sei denn,isMutedisttrue:

Da Ihr Effekt nunisMutedin seinem Code verwendet, müssen Sie es zu den Abhängigkeiten hinzufügen:

Das Problem ist, dass jedes Mal, wenn sichisMutedändert (z. B. wenn der Benutzer den „Stumm“-Schalter drückt), der Effekt neu synchronisiert wird und die Verbindung zum Chat erneut herstellt. Das ist nicht die gewünschte Benutzererfahrung! (In diesem Beispiel würde selbst das Deaktivieren des Linters nicht funktionieren – wenn Sie das tun, würdeisMutedmit seinem alten Wert „stecken bleiben“.)

Um dieses Problem zu lösen, müssen Sie die Logik, die nicht reaktiv sein soll, aus dem Effekt extrahieren. Sie möchten nicht, dass dieser Effekt auf Änderungen vonisMuted„reagiert“.Verschieben Sie diesen nicht-reaktiven Teil der Logik in einen Effekt-Ereignis:

Effekt-Ereignisse ermöglichen es Ihnen, einen Effekt in reaktive Teile (die auf reaktive Werte wieroomIdund deren Änderungen „reagieren“ sollten) und nicht-reaktive Teile (die nur ihre neuesten Werte lesen, wieonMessage isMutedliest) aufzuteilen.Da SieisMutedjetzt innerhalb eines Effekt-Ereignisses lesen, muss es keine Abhängigkeit Ihres Effekts mehr sein.Dadurch wird der Chat nicht mehr neu verbunden, wenn Sie die „Stumm“-Einstellung ein- und ausschalten, was das ursprüngliche Problem löst!

Einen Event-Handler aus den Props umschließen

Sie könnten auf ein ähnliches Problem stoßen, wenn Ihre Komponente einen Event-Handler als Prop erhält:

Angenommen, die übergeordnete Komponente übergibt bei jedem Render eineandereonReceiveMessage-Funktion:

DaonReceiveMessageeine Abhängigkeit ist, würde dies dazu führen, dass der Effekt nach jedem erneuten Rendern der übergeordneten Komponente neu synchronisiert wird. Dies würde dazu führen, dass er sich erneut mit dem Chat verbindet. Um dies zu lösen, wickeln Sie den Aufruf in ein Effekt-Ereignis:

Effekt-Ereignisse sind nicht reaktiv, daher müssen Sie sie nicht als Abhängigkeiten angeben. Dadurch wird der Chat nicht mehr neu verbunden, selbst wenn die übergeordnete Komponente eine Funktion übergibt, die bei jedem erneuten Rendern anders ist.

Reaktiven und nicht-reaktiven Code trennen

In diesem Beispiel möchten Sie einen Besuch protokollieren, jedes Mal wenn sichroomIdändert. Sie möchten die aktuellenotificationCountin jedes Protokoll aufnehmen, aber Siemöchten nicht, dass eine Änderung vonnotificationCountein Protokollereignis auslöst.

Die Lösung besteht erneut darin, den nicht-reaktiven Code in ein Effekt-Ereignis auszulagern:

Sie möchten, dass Ihre Logik bezüglichroomIdreaktiv ist, also lesen SieroomIdinnerhalb Ihres Effects. Sie möchten jedoch nicht, dass eine Änderung vonnotificationCounteinen zusätzlichen Besuch protokolliert, also lesen SienotificationCountinnerhalb des Effect Events.Erfahren Sie mehr über das Lesen der neuesten Props und des States aus Effects mithilfe von Effect Events.

Ändert sich ein reaktiver Wert unbeabsichtigt?

Nehmen wir zum Beispiel an, Sie erstellen einoptions-Objekt im Hauptteil Ihrer Komponente und lesen dann dieses Objekt innerhalb Ihres Effects:

Dieses Objekt wird im Komponentenhauptteil deklariert, daher ist es einreaktiver Wert.Wenn Sie einen solchen reaktiven Wert innerhalb eines Effects lesen, deklarieren Sie ihn als Abhängigkeit. Dadurch wird sichergestellt, dass Ihr Effect auf seine Änderungen „reagiert“:

Es ist wichtig, ihn als Abhängigkeit zu deklarieren! Dadurch wird beispielsweise sichergestellt, dass Ihr Effect bei einer Änderung vonroomId mit den neuen optionserneut eine Verbindung zum Chat herstellt. Allerdings gibt es auch ein Problem mit dem obigen Code. Um es zu sehen, versuchen Sie, in die Eingabe im folgenden Sandbox zu tippen, und beobachten Sie, was in der Konsole passiert:

In der obigen Sandbox aktualisiert die Eingabe nur die Zustandsvariablemessage. Aus der Perspektive des Benutzers sollte dies die Chat-Verbindung nicht beeinflussen. Allerdings wird jedes Mal, wenn Sie diemessageaktualisieren, Ihre Komponente neu gerendert. Wenn Ihre Komponente neu gerendert wird, wird der Code darin von Grund auf neu ausgeführt.

Bei jedem erneuten Rendern deroptions-Objekt von Grund auf erstellt. React erkennt, dass dasChatRoom-Komponente wird ein neuesoptions-Objekt einanderes Objektist als dasoptions-Objekt, das während des letzten Renderings erstellt wurde. Deshalb synchronisiert es Ihren Effect (der vonoptionsabhängt) erneut, und der Chat verbindet sich beim Tippen erneut.

Dieses Problem betrifft nur Objekte und Funktionen. In JavaScript wird jedes neu erstellte Objekt und jede neu erstellte Funktion als von allen anderen verschieden betrachtet. Es spielt keine Rolle, dass die Inhalte darin gleich sein mögen!

Objekte und Funktionen als Abhängigkeiten können dazu führen, dass sich Ihr Effekt häufiger neu synchronisiert als nötig.

Deshalb sollten Sie, wann immer möglich, versuchen, Objekte und Funktionen als Abhängigkeiten Ihres Effekts zu vermeiden. Versuchen Sie stattdessen, sie außerhalb der Komponente, innerhalb des Effekts zu platzieren oder primitive Werte daraus zu extrahieren.

Statische Objekte und Funktionen außerhalb Ihrer Komponente verschieben

Wenn das Objekt nicht von Props oder State abhängt, können Sie es außerhalb Ihrer Komponente verschieben:

Auf diese WeisebeweisenSie dem Linter, dass es nicht reaktiv ist. Es kann sich nicht durch ein erneutes Rendern ändern, daher muss es keine Abhängigkeit sein. Ein erneutes Rendern vonChatRoomführt nun nicht mehr dazu, dass sich Ihr Effekt neu synchronisiert.

Das funktioniert auch für Funktionen:

DacreateOptionsaußerhalb Ihrer Komponente deklariert ist, handelt es sich nicht um einen reaktiven Wert. Deshalb muss es nicht in den Abhängigkeiten Ihres Effekts angegeben werden und wird niemals dazu führen, dass sich Ihr Effekt neu synchronisiert.

Dynamische Objekte und Funktionen innerhalb Ihres Effekts verschieben

Wenn Ihr Objekt von einem reaktiven Wert abhängt, der sich durch ein erneutes Rendern ändern kann, wie z. B. eineroomId-Prop, können Sie es nichtaußerhalbIhrer Komponente ziehen. Sie können seine Erstellung jedochinnerhalbdes Codes Ihres Effekts verschieben:

Da optionsnun innerhalb Ihres Effekts deklariert ist, ist es keine Abhängigkeit Ihres Effekts mehr. Stattdessen ist der einzige reaktive Wert, den Ihr Effekt verwendet,roomId. DaroomIdkein Objekt oder keine Funktion ist, können Sie sicher sein, dass es nichtversehentlichanders ist. In JavaScript werden Zahlen und Zeichenketten anhand ihres Inhalts verglichen:

Dank dieser Korrektur verbindet sich der Chat nicht mehr neu, wenn Sie die Eingabe bearbeiten:

Allerdingsverbindetes sich neu, wenn Sie dieroomIdDropdown-Liste ändern, wie zu erwarten.

Das funktioniert auch für Funktionen:

Sie können eigene Funktionen schreiben, um Teile der Logik innerhalb Ihres Effects zu gruppieren. Solange Sie sie auchinnerhalbIhres Effects deklarieren, sind sie keine reaktiven Werte und müssen daher keine Abhängigkeiten Ihres Effects sein.

Primitive Werte aus Objekten lesen

Manchmal erhalten Sie ein Objekt von Props:

Das Risiko hierbei ist, dass die übergeordnete Komponente das Objekt während des Renderns erstellt:

Das würde dazu führen, dass sich Ihr Effect bei jedem erneuten Rendern der übergeordneten Komponente neu verbindet. Um dies zu beheben, lesen Sie die Informationen aus dem Objektaußerhalbdes Effects und vermeiden Sie Objekt- und Funktionsabhängigkeiten:

Die Logik wird etwas repetitiv (Sie lesen einige Werte aus einem Objekt außerhalb eines Effects und erstellen dann ein Objekt mit denselben Werten innerhalb des Effects). Aber es macht sehr deutlich, von welchen Informationen Ihr Effecttatsächlichabhängt. Wenn ein Objekt unbeabsichtigt von der übergeordneten Komponente neu erstellt wird, würde sich der Chat nicht neu verbinden. Wenn jedochoptions.roomIdoderoptions.serverUrltatsächlich unterschiedlich sind, würde sich der Chat neu verbinden.

Primitive Werte aus Funktionen berechnen

Derselbe Ansatz kann auch für Funktionen funktionieren. Angenommen, die übergeordnete Komponente übergibt eine Funktion:

Um sie nicht zu einer Abhängigkeit zu machen (und eine Neuverbindung bei erneuten Renderings zu verursachen), rufen Sie sie außerhalb des Effects auf. Dies gibt Ihnen dieroomId- undserverUrl-Werte, die keine Objekte sind und die Sie innerhalb Ihres Effects lesen können:

Dies funktioniert nur fürreineFunktionen, da sie sicher während des Renderns aufgerufen werden können. Wenn Ihre Funktion ein Event-Handler ist, Sie aber nicht möchten, dass ihre Änderungen Ihren Effect erneut synchronisieren,verpacken Sie sie stattdessen in einen Effect Event.

Zusammenfassung

  • Abhängigkeiten sollten immer mit dem Code übereinstimmen.
  • Wenn Sie mit Ihren Abhängigkeiten nicht zufrieden sind, müssen Sie den Code bearbeiten.
  • Das Unterdrücken des Linters führt zu sehr verwirrenden Fehlern, und Sie sollten es stets vermeiden.
  • Um eine Abhängigkeit zu entfernen, müssen Sie dem Linter "beweisen", dass sie nicht notwendig ist.
  • Wenn ein Code als Reaktion auf eine bestimmte Interaktion ausgeführt werden soll, verschieben Sie diesen Code in einen Event-Handler.
  • Wenn verschiedene Teile Ihres Effekts aus unterschiedlichen Gründen neu ausgeführt werden sollen, teilen Sie ihn in mehrere Effekte auf.
  • Wenn Sie einen Zustand basierend auf dem vorherigen Zustand aktualisieren möchten, übergeben Sie eine Updater-Funktion.
  • Wenn Sie den neuesten Wert lesen möchten, ohne ihn zu "reagieren", extrahieren Sie einen Effekt-Ereignis aus Ihrem Effekt.
  • In JavaScript werden Objekte und Funktionen als unterschiedlich betrachtet, wenn sie zu unterschiedlichen Zeiten erstellt wurden.
  • Versuchen Sie, Objekt- und Funktionsabhängigkeiten zu vermeiden. Verschieben Sie sie außerhalb der Komponente oder innerhalb des Effekts.

Try out some challenges

Challenge 1 of 4:Fix a resetting interval #

This Effect sets up an interval that ticks every second. You’ve noticed something strange happening: it seems like the interval gets destroyed and re-created every time it ticks. Fix the code so that the interval doesn’t get constantly re-created.