React-Anwendungen bestehen aus Komponenten, und jede Komponente führt ein eigenes Leben. Sie erscheint auf dem Bildschirm. Sie reagiert auf neue Informationen. Schließlich verschwindet sie. Ignoriert man diesen Rhythmus, hat das reale Konsequenzen. Memory Leaks schleichen sich ein. Die Render-Performance verschlechtert sich. Benutzer klicken auf Schaltflächen, die nicht mehr reagieren, weil die mit ihnen verknüpfte Komponente vor zehn Minuten bereits unmounted wurde, der Event-Listener aber noch aktiv ist. Das Verständnis des Component Lifecycles ist keine rein akademische Übung. Es ist das Fundament für die Entwicklung von Software, die unter realen Bedingungen zuverlässig bleibt.
Stellen Sie sich die Existenz einer Komponente in drei Phasen vor. Entwickler beschreiben sie oft als Geburt, Wachstum und Tod. React nennt sie Mounting, Updating und Unmounting. Jede Phase hat eine spezifische Aufgabe, und jede bietet Ihnen einen präzisen Moment, um Code auszuführen oder aufzuräumen.
Die drei Phasen
Mounting ist die Geburt. Die Komponente wird erstellt und zum ersten Mal in das Browser-DOM eingefügt. Dies ist Ihr Setup-Zeitfenster. Wenn die Komponente Remote-Daten benötigt, ist dies der Zeitpunkt, an dem Sie diese abrufen. Wenn sie einen initialen State benötigt, der aus Props berechnet wird, tun Sie dies hier. In der Ära der Class Components war dies das Terrain von componentDidMount. Mit modernen Functional Components handhaben Sie dies mit useEffect und einem leeren Dependency-Array. Das entscheidende Detail ist, dass dieser Codeblock genau einmal ausgeführt wird, unmittelbar nachdem React das Element in die Seite eingefügt hat. Das macht ihn ideal für einmalige Setups, wie das Abrufen eines Benutzerprofils oder das Lesen eines Wertes aus dem localStorage.
Updating ist das Wachstum. Eine gemountete Komponente verharrt nicht in Ruhe. Props kommen von einer Parent-Komponente. Der State ändert sich durch eine Benutzerinteraktion. Die Parent-Komponente selbst rendert neu, was das Child dazu zwingt, zu folgen. React rendert die Komponente dann neu, um die UI mit Ihren Daten synchron zu halten. Diese Phase wiederholt sich viele Male während des Lebens einer Komponente. Jedes Mal, wenn sich eine Dependency ändert, werden Ihre Effects erneut ausgeführt, und die Komponente liefert neue Ausgaben an das DOM zurück. Da diese Phase so häufig ausgelöst wird, ist sie auch der Ort, an dem die meisten Performance-Probleme entstehen. Unnötige Arbeit häuft sich hier schnell an.
Unmounting ist der Tod. Die Komponente verschwindet vom Bildschirm, vielleicht weil der Benutzer zu einer anderen Seite navigiert ist oder ein Conditional Render sie ausgeschaltet hat. Zu diesem Zeitpunkt wird die Komponente zerstört, aber die Außenwelt weiß das nicht immer. Timer laufen weiter. WebSockets hören weiter zu. Event-Listener am window-Objekt bleiben bestehen. Wenn Sie diese nicht bereinigen, halten sie Referenzen auf tote Komponenten und verursachen Memory Leaks. Der Browser verschwendet Zyklen für Geister. React stellt Ihnen eine Cleanup-Funktion zur Verfügung, damit Sie genau dann Intervalle stoppen, Verbindungen schließen und Listener entfernen können, bevor die Komponente endgültig verschwindet.
Von Class-Methoden zu Hooks
Jahrelang verwalteten React-Ingenieure diese Phasen über Class Components. Die Logik war auf verschiedene Methoden aufgeteilt. Sie haben Daten innerhalb von componentDidMount abgerufen, auf Prop-Änderungen innerhalb von componentDidUpdate reagiert und den Boden innerhalb von componentWillUnmount gefegt. Das Problem war, dass die zusammengehörige Logik verstreut war. Eine einzige Funktion, wie etwa eine Live-Chat-Verbindung, erforderte Code in drei separaten Lifecycle-Methoden, nur um die Verbindung herzustellen, auf Thread-Änderungen zu prüfen und die Verbindung wieder zu trennen.
Hooks haben das geändert. Der useEffect-Hook in Functional Components ermöglicht es Ihnen, die Logik nach Zweck statt nach Lifecycle-Phase zu gruppieren. Dennoch lässt sich das mentale Modell sauber abbilden, wenn man weiß, wonach man suchen muss.
Um das Mounting zu handhaben, schreiben Sie useEffect(() => { ... }, []). Das leere Dependency-Array teilt React mit, dass dieser Effect keine externen Abhängigkeiten hat und daher nur nach dem initialen Render ausgeführt wird. Dies ersetzt componentDidMount.
Um Updates zu handhaben, geben Sie die spezifischen Werte an, die React beobachten soll: useEffect(() => { ... }, [dependency]). Wenn sich dependency zwischen den Renders ändert,
