Menu

React Lifecycle einer Komponente: Mount, Update, Unmount

Jede React-Komponente wird gemountet (erscheint), aktualisiert (rendert erneut) und unmountet (wird entfernt). Lerne, wie jede Phase zu useEffect passt, die Lifecycle-Methoden von Klassen und ihre Hook-Gegenstücke sowie die Render- und Commit-Phase.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

Der Lifecycle einer React-Komponente hat drei Phasen: Mounten (die Komponente erscheint zum ersten Mal auf dem Bildschirm), Aktualisieren (sie rendert erneut, weil sich ihr State, ihre Props oder ihr Context geändert haben) und Unmounten (sie wird entfernt). In Funktionskomponenten reagierst du mit useEffect auf diese Phasen: Ein Effekt mit [] läuft nach dem Mounten, ein Effekt mit Abhängigkeiten läuft nach Updates, in denen sie sich geändert haben, und die Funktion, die ein Effekt zurückgibt, läuft beim Unmounten.

Die Konsole unter der Vorschau zeigt jede Phase, während sie passiert.

Die Konsole beginnt mit render, count = 0 und mounted. Jeder Klick auf Count loggt einen Render und ein Update. Unmount loggt unmounted; erneutes Mount beginnt wieder bei count = 0, weil der State mit der Komponente verworfen wurde.

Mounten

Eine Komponente wird gemountet, wenn React sie zum ersten Mal an einer bestimmten Stelle im Baum rendert. React ruft die Funktion auf, erzeugt aus dem zurückgegebenen JSX die DOM-Knoten, fügt sie ein, lässt den Browser zeichnen und führt dann die Effekte der Komponente aus.

useEffect(fn, []) ist der Ort, an dem du Dinge startest, die existieren sollen, solange die Komponente auf dem Bildschirm ist: ein Abonnement, einen Timer, eine Verbindung, eine erste Datenanfrage. Er läuft nach dem Zeichnen, verzögert also nie den ersten Frame.

Aktualisieren

Eine Komponente aktualisiert sich (rendert erneut), wenn:

  • sich ihr eigener State ändert,
  • ihr Elternteil erneut rendert (standardmäßig rendert dann jedes Kind mit, ob sich seine Props geändert haben oder nicht),
  • sich ein Context ändert, den sie liest.

Nach jedem Update führt React die Effekte aus, deren Abhängigkeiten sich geändert haben. Bevor ein Effekt erneut läuft, führt React das vorherige Cleanup dieses Effekts aus, also wird das alte Abonnement geschlossen, bevor das neue öffnet. Die Seite zum Rendern behandelt genauer, was einen Render auslöst.

Unmounten

Eine Komponente wird unmountet, wenn ihr Elternteil sie nicht mehr rendert (wie {show && <Counter />} oben), wenn sich ihr key ändert oder wenn der Root selbst unmountet wird. React entfernt ihre DOM-Knoten, führt das Cleanup jedes Effekts aus und verwirft ihren State. Wenn die Komponente später wieder erscheint, ist sie eine brandneue Instanz.

Eltern und Kinder

React rendert von oben nach unten, führt Effekte aber von unten nach oben aus. Wenn ein Elternteil und ein Kind gemeinsam gemountet werden, laufen die Effekte des Kindes zuerst, also kann sich der Effekt eines Elternteils darauf verlassen, dass seine Kinder vollständig eingerichtet sind.

Das Mounten loggt render Parent, render Child, Child effect, Parent effect. Drück Remove, und die Cleanups laufen andersherum: Parent cleanup, dann Child cleanup.

Render- und Commit-Phase

Jedes Update durchläuft zwei Phasen:

  1. Render-Phase. React ruft deine Komponenten auf, um das neue JSX zu berechnen, und vergleicht es mit dem vorherigen Ergebnis. Auf dem Bildschirm ändert sich noch nichts. React kann diese Arbeit pausieren, im StrictMode zweimal ausführen oder verwerfen, deshalb muss das Rendern pur sein: keine Anfragen, keine Abonnements, keine Änderungen an äußeren Variablen.
  2. Commit-Phase. React wendet die Unterschiede auf das DOM an, hängt Refs an und führt die Callbacks von useLayoutEffect aus, alles bevor der Browser zeichnet. Die Callbacks von useEffect laufen danach, meist nachdem der Browser gezeichnet hat. Wenn ein Klick oder eine andere diskrete Eingabe das Update ausgelöst hat, führt React sie stattdessen direkt nach den Layout-Effekten aus, damit das Ergebnis vor dem nächsten Event bereit ist.

Jeder Klick loggt die drei Zeilen in derselben Reihenfolge. Diese Effekte haben kein Abhängigkeitsarray, also laufen sie nach jedem Render. Gib beiden [] als zweites Argument, und sie laufen nur nach dem ersten.

Lifecycle-Methoden von Klassen und ihre Hook-Gegenstücke

Klassenkomponenten schreiben den Lifecycle als benannte Methoden aus. Du begegnest ihnen in älterem Code und in Error Boundaries, die weiterhin eine Klasse brauchen.

KlassenmethodeWann sie läuftGegenstück in Funktionskomponenten
constructoreinmal, vor dem ersten RenderuseState(initial), useRef
static getDerivedStateFromPropsvor jedem Renderden Wert beim Rendern berechnen oder mit einem key zurücksetzen
renderbei jedem Renderder Funktionskörper
componentDidMountnachdem der erste Render im DOM istuseEffect(fn, [])
shouldComponentUpdatevor einem Update, kann es überspringenReact.memo (es gibt die umgekehrte Antwort: „sind die Props gleich“)
getSnapshotBeforeUpdatedirekt bevor sich das DOM ändertkein direkter Hook; useLayoutEffect mit einer Ref kommt am nächsten
componentDidUpdatenach jedem UpdateuseEffect(fn, [deps]) (läuft auch nach dem Mounten)
componentWillUnmountvor dem Entfernendas von useEffect zurückgegebene Cleanup
getDerivedStateFromError, componentDidCatchwenn ein Kind einen Fehler wirftkeins: schreib eine Error-Boundary-Klasse

Hier ist eine Klasse, die jede Methode loggt, während sie läuft:

Das Mounten loggt constructor, getDerivedStateFromProps, render, componentDidMount. Ein Klick loggt getDerivedStateFromProps, shouldComponentUpdate, render, getSnapshotBeforeUpdate, componentDidUpdate. Lass shouldComponentUpdate false zurückgeben, und Klicks aktualisieren den Button nicht mehr: Der State ändert sich, aber React überspringt den Render. Die Seite zu Klassenkomponenten zeigt, wie du eine solche Klasse in eine Funktion umwandelst.

In Synchronisation denken, nicht in Lifecycle

Die Hook-Tabelle ist nützlich, um alten Code zu lesen, kann dich aber dazu verleiten, Effekte zu schreiben, die Gewohnheiten aus Klassen kopieren, etwa einen großen Effekt für „did mount“ und einen großen für „did update“. Ein Effekt liest sich besser als „halte dieses äußere Ding synchron mit diesen Werten“: verbinde dich mit roomId, und wenn sich roomId ändert, trenne und verbinde neu. Schreib einen Effekt pro Ding, das du synchronisierst, führe die Werte, die er nutzt, als Abhängigkeiten auf und lass React entscheiden, wann er läuft.

Häufig gestellte Fragen

Welche Phasen hat der Lifecycle einer React-Komponente?

Mounten (React erzeugt die Komponente und bringt ihre Ausgabe auf den Bildschirm), Aktualisieren (sie rendert erneut, weil sich ihr State, ihre Props oder ihr Context geändert haben) und Unmounten (sie wird entfernt und räumt auf).

Was ist das Hook-Gegenstück zu componentDidMount?

useEffect(() => { ... }, []). Das leere Abhängigkeitsarray lässt ihn einmal laufen, nachdem der erste Render auf dem Bildschirm ist. Die Funktion, die er zurückgibt, entspricht componentWillUnmount.

Was ist das Hook-Gegenstück zu componentDidUpdate?

useEffect mit den Werten, die dich interessieren, im Abhängigkeitsarray, etwa [userId]. Anders als componentDidUpdate läuft er auch nach dem ersten Render, deckt also Mount und Update zusammen ab.

In welcher Reihenfolge laufen die Effekte von Eltern und Kindern?

React rendert vom Elternteil nach unten, führt Effekte aber von den Kindern nach oben aus: Der Effekt eines Kindes läuft vor dem seines Elternteils. Beim Unmounten läuft das Cleanup des Elternteils vor dem des Kindes.

Was sind die Render- und die Commit-Phase?

In der Render-Phase ruft React deine Komponenten auf, um herauszufinden, wie der Bildschirm aussehen soll; diese Arbeit kann es pausieren oder verwerfen. In der Commit-Phase wendet es die Änderungen auf das DOM an und führt Layout-Effekte aus; normale Effekte laufen danach, meist nachdem der Browser gezeichnet hat.

Illustration der Programmiersprachen bei Coddy

Lerne mit Coddy zu programmieren

LOS GEHT'S