Kodokon kodokon.com

useEffect: Effekte, Abhängigkeiten, Cleanup

Synchronisiere deine Komponenten mit der Außenwelt über useEffect und meistere Abhängigkeiten und Cleanup.

9 Min. · 3 Fragen

Diese Lektion in Kodokon öffnen

Eine React-Komponente berechnet JSX aus Props und State. Alles außerhalb dieses Rahmens - den Dokumenttitel ändern, einen Timer starten, ein Browser-Event abonnieren - ist ein Seiteneffekt. useEffect führt diesen Code nach dem Rendern aus, ohne die Anzeige zu blockieren, und synchronisiert ihn neu, wenn sich bestimmte Werte ändern.

JSX
import { useEffect } from "react";

function CartTitle({ count }) {
  useEffect(() => {
    document.title = `Cart (${count})`;
  }, [count]);

  return <p>Items: {count}</p>;
}
Der Effekt läuft nur erneut, wenn sich count ändert.

Das Abhängigkeitsarray steuert, wie oft der Effekt läuft. [count]: Der Effekt läuft nach jedem Rendern erneut, bei dem sich count geändert hat. []: Der Effekt läuft nur einmal, nach dem ersten Rendern. Kein Array: Der Effekt läuft nach jedem Rendern erneut, was selten das ist, was du willst. Goldene Regel: Jeder Wert der Komponente, der im Effekt verwendet wird, muss im Array auftauchen.

JSX
import { useEffect, useState } from "react";

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const id = setInterval(() => {
      setSeconds((s) => s + 1);
    }, 1000);

    return () => clearInterval(id);
  }, []);

  return <p>Elapsed: {seconds} s</p>;
}
Ohne clearInterval würde der Timer die Komponente überleben.

Die vom Effekt zurückgegebene Funktion ist die Cleanup-Funktion. React ruft sie vor jedem neuen Durchlauf des Effekts auf, dann ein letztes Mal, wenn die Komponente ausgehängt wird. Sie ist es, die Lecks verhindert: verwaiste Timer, sich stapelnde Listener, Abonnements, die nie gekündigt werden. Jeder Effekt, der etwas „öffnet“, muss es auch wieder schließen.

JSX
useEffect(() => {
  function onResize() {
    setWidth(window.innerWidth);
  }
  window.addEventListener("resize", onResize);

  return () => {
    window.removeEventListener("resize", onResize);
  };
}, []);
Abonnieren des resize-Events, gekündigt beim Aushängen.

Wissenscheck

Stelle sicher, dass du die wichtigsten Punkte dieser Lektion behalten hast.

  1. Wann wird die Funktion fn bei useEffect(fn, []) ausgeführt?
    • Vor jedem Rendern der Komponente
    • Nur nach dem ersten Rendern
    • Bei jeder State-Aktualisierung
  2. Wann wird die von einem Effekt zurückgegebene Cleanup-Funktion aufgerufen?
    • Nur wenn die Komponente ausgehängt wird
    • Vor jedem erneuten Durchlauf des Effekts und beim Aushängen
    • Direkt vor dem ersten Rendern der Komponente
    • Nie automatisch: Du musst sie selbst aufrufen
  3. Ein Effekt liest userId, aber sein Abhängigkeitsarray ist []. Wo liegt das Problem?
    • Der Effekt läuft nicht erneut, wenn sich userId ändert, und behält einen veralteten Wert
    • React wirft beim ersten Rendern einen Fehler
    • Der Effekt läuft in einer Endlosschleife erneut