Der useEffect-Hook richtig einsetzen

useEffect erlaubt dir, Seiteneffekte wie Datenabrufe oder Timer in React zu steuern. Hier lernst du das Dependency-Array und das Cleanup richtig kennen.

Teilen
Der useEffect-Hook richtig einsetzen

Komponenten zeigen nicht nur Daten an – manchmal müssen sie auch mit der Außenwelt interagieren: Daten von einer API laden, einen Timer starten oder den Dokumenttitel ändern. Genau dafür gibt es den useEffect-Hook. In diesem Beitrag zeige ich dir, wie du Seiteneffekte sauber steuerst und das gefürchtete Dependency-Array verstehst.

Was ist ein Seiteneffekt?

Ein Seiteneffekt ist alles, was außerhalb des reinen Renderns passiert: ein Netzwerkaufruf, ein setTimeout, ein Event-Listener oder der Zugriff auf den Browser. useEffect sorgt dafür, dass solcher Code nach dem Rendern ausgeführt wird, ohne die Anzeige zu blockieren.

import { useEffect } from "react";

function Titel() {
  useEffect(() => {
    document.title = "Willkommen!";
  });

  return <h1>Hallo</h1>;
}

Das Dependency-Array

Der zweite Parameter von useEffect ist das Dependency-Array. Es bestimmt, wann der Effekt erneut läuft:

  • Kein Array: Der Effekt läuft nach jedem Rendern.
  • Leeres Array []: Der Effekt läuft nur einmal, beim ersten Rendern.
  • Array mit Werten: Der Effekt läuft, wenn sich einer dieser Werte ändert.
function Begruessung({ name }) {
  useEffect(() => {
    console.log("Name hat sich geändert:", name);
  }, [name]);

  return <p>Hallo {name}</p>;
}

Hier läuft der Effekt nur, wenn sich name ändert. Das verhindert unnötige Ausführungen.

Daten von einer API laden

Ein sehr häufiger Anwendungsfall ist das Laden von Daten beim ersten Rendern. Dafür kombinierst du useEffect mit einem leeren Dependency-Array und useState:

function Nutzerliste() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetch("https://api.example.com/users")
      .then((res) => res.json())
      .then((daten) => setUsers(daten));
  }, []);

  return (
    <ul>
      {users.map((u) => (
        <li key={u.id}>{u.name}</li>
      ))}
    </ul>
  );
}

Das leere Array sorgt dafür, dass die Daten nur einmal geladen werden und nicht bei jedem Rendern erneut.

Aufräumen mit der Cleanup-Funktion

Manche Effekte hinterlassen Spuren: Timer laufen weiter, Event-Listener bleiben aktiv. Damit nichts hängen bleibt, kann dein Effekt eine Cleanup-Funktion zurückgeben. React ruft sie auf, bevor der Effekt erneut läuft oder die Komponente verschwindet:

function Uhr() {
  const [zeit, setZeit] = useState(new Date());

  useEffect(() => {
    const id = setInterval(() => setZeit(new Date()), 1000);
    return () => clearInterval(id);
  }, []);

  return <p>{zeit.toLocaleTimeString()}</p>;
}

Ohne clearInterval würde der Timer auch nach dem Entfernen der Komponente weiterlaufen und Speicher verschwenden. Die Cleanup-Funktion ist deshalb keine Kür, sondern Pflicht.

Häufige Fehler vermeiden

Ein klassischer Fehler ist ein unvollständiges Dependency-Array. Wenn dein Effekt eine Variable nutzt, sie aber nicht im Array steht, arbeitet er mit veralteten Werten. React-Linter warnen dich davor. Ein weiterer Stolperstein: State direkt im Effekt zu setzen, ohne Bedingung, führt schnell zu einer Endlosschleife:

// Vorsicht: Endlosschleife!
useEffect(() => {
  setCount(count + 1); // löst Re-Render aus -> Effekt läuft wieder
});

Setze hier ein passendes Dependency-Array oder eine Bedingung, damit der Effekt nicht endlos feuert.

Fazit

Mit useEffect verbindest du deine React-Komponenten mit der Außenwelt. Der Schlüssel ist das Dependency-Array: Es entscheidet, wann der Effekt läuft. Vergiss bei Timern und Listenern niemals die Cleanup-Funktion, und achte darauf, alle genutzten Werte als Abhängigkeiten anzugeben. Wenn du diese Regeln beachtest, bleiben deine Effekte vorhersehbar und frei von typischen Bugs. Als Nächstes schauen wir uns an, wie du Listen und Formulare in React elegant darstellst.