React Hooks — was sie sind, wichtige Hooks und Nutzungsregeln

Autor: IT Sectr Veröffentlicht: 2026-07-04 Lesezeit: 10 Min.

React Hooks sind Funktionen, die es ermöglichen, State, Effekte, Context und andere React-Funktionen in funktionalen Komponenten zu verwenden, ohne Klassen zu schreiben. Mit React 16.8 eingeführt, haben Hooks den Entwicklungsansatz radikal verändert und komplexe Patterns wie HOC und render props ersetzt. Laut React, 2024 gibt es 15 eingebaute Hooks, die alle Szenarien der Komponentenverwaltung abdecken.

Das Wichtigste

  • Hooks — Funktionen zum Anbinden von React-Funktionen an funktionale Komponenten ohne extends Component.
  • useState — der grundlegende Hook für die Zustandsverwaltung, gibt einen Wert und einen Setter zurück.
  • useEffect — für Nebeneffekte: API-Anfragen, Abonnements, Timer, DOM-Manipulationen.
  • useContext — für den Zugriff auf den React-Kontext ohne Consumer-Wrapper und static contextType.
  • Hook-Regeln — nur auf der obersten Ebene und nur innerhalb von funktionalen Komponenten oder benutzerdefinierten Hooks aufrufen.

Was sind React Hooks?

React Hooks sind eine Reihe von in React integrierten Funktionen, die es ermöglichen, sich in die internen Mechanismen des Frameworks einzuklinken, ohne Klassen zu erstellen. Vor React 16.8 konnten funktionale Komponenten nur Props akzeptieren und JSX zurückgeben — jede komplexe Logik erforderte eine Klassenkomponente.

Das Problem bei Klassenkomponenten ist die Aufteilung zusammengehöriger Logik. Code, der zu einer Entität gehört (z. B. ein WebSocket-Abonnement), wurde zwangsweise auf componentDidMount, componentDidUpdate und componentWillUnmount aufgeteilt. Hooks lösen dies: Die gesamte Logik wird in einem useEffect gruppiert.

Das zweite Problem ist die Wiederverwendung von Logik. Um Zustandslogik zwischen Klassenkomponenten wiederzuverwenden, musste man HOC (Higher-Order Components) oder render props anwenden — beide Patterns erzeugten zusätzliche Verschachtelung im Komponentenbaum. Benutzerdefinierte Hooks lösen dies ohne Verschachtelung.

useState — Zustandsverwaltung

useState ist der grundlegendste Hook. Er nimmt einen Anfangswert entgegen und gibt ein Tupel zurück: den aktuellen Wert und eine Funktion zu dessen Aktualisierung. Im Gegensatz zu this.setState in Klassen führt useState keine Objektzusammenführung durch — der neue Zustand ersetzt den vorherigen für einen bestimmten useState-Aufruf vollständig.

js
import React, { useState } from 'react';

function Form() {
  const [text, setText] = useState('');
  const [submitting, setSubmitting] = useState(false);

  async function handleSubmit() {
    setSubmitting(true);
    await fetch('/api/submit', {
      method: 'POST',
      body: JSON.stringify({ text })
    });
    setSubmitting(false);
  }

  return (
    <div>
      <input
        value={text}
        onChange={e => setText(e.target.value)}
      />
      <button onClick={handleSubmit}
        disabled={submitting}>
        {submitting ? 'Saving...' : 'Submit'}
      </button>
    </div>
  );
}

Funktionale Form von setState

Der Setter von useState kann eine Funktion akzeptieren, die den vorherigen Wert erhält und einen neuen zurückgibt. Die funktionale Form ist erforderlich, wenn der neue Zustand aus dem vorherigen berechnet wird und gebündelte setState-Aufrufe möglich sind — jeder Aufruf erhält den aktuellen vorherigen Wert.

useEffect — Nebeneffekte und Lebenszyklus

useEffect ist ein Hook zur Durchführung von Nebeneffekten in funktionalen Komponenten. Er nimmt zwei Argumente entgegen: eine Effektfunktion und ein Abhängigkeitsarray. React führt den Effekt nach jedem Rendern aus, aber wenn Abhängigkeiten angegeben sind — nur wenn sich eine davon ändert.

Ein leeres Abhängigkeitsarray [] bedeutet, dass der Effekt einmal nach dem ersten Rendern ausgeführt wird (analog zu componentDidMount). Die Rückgabe einer Funktion aus dem Effekt ist eine Bereinigung, die beim Unmount (analog zu componentWillUnmount) und vor der erneuten Ausführung des Effekts ausgeführt wird.

js
import React, { useState, useEffect } from 'react';

function ChatRoom({ roomId }) {
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    const socket = new WebSocket(`wss://chat/${roomId}`);

    socket.onmessage = (event) => {
      setMessages(prev => [...prev, JSON.parse(event.data)]);
    };

    // Bereinigung - Socket schließen
    return () => socket.close();
  }, [roomId]);

  return <ul>
    {messages.map((msg, i) =>
      <li key={i}>{msg.text}</li>
    )}
  </ul>;
}

Die Abhängigkeiten von useEffect sind die einzige Verbindung zwischen dem Effekt und der Außenwelt. Wenn der Effekt eine Variable aus Props oder State verwendet, muss sie im Abhängigkeitsarray stehen. Das Ignorieren dieser Regel ist eine Fehlerquelle mit veralteten Closures (stale closures).

useContext — Zugriff auf den Kontext

useContext ist ein Hook zum Lesen von Kontextwerten. Er nimmt ein von React.createContext erstelltes Kontextobjekt entgegen und gibt den aktuellen Wert zurück. Wenn sich der Kontext ändert, wird die Komponente automatisch mit dem neuen Wert neu gerendert.

Vor useContext erforderte der Zugriff auf den Kontext in funktionalen Komponenten die Umwickelung in Context.Consumer, was Verschachtelung erzeugte. useContext eliminiert Consumer vollständig — rufen Sie den Hook einfach an einer beliebigen Stelle in der funktionalen Komponente auf.

js
import React, { createContext, useContext } from 'react';

const ThemeContext = createContext('hell');

function ThemedButton() {
  const theme = useContext(ThemeContext);

  return <button
    className={`btn btn-${theme}`}
  >
    {theme === 'dark' ? 'moon' : '☀️'}
  </button>;
}

useContext ist kein Ersatz für Redux oder globalen Zustand. React empfiehlt, Kontext für selten wechselnde Werte zu verwenden — Theme, Locale, Authentifizierungsstatus. Bei häufig aktualisierten Daten wird bei jedem erneuten Rendern die gesamten Kontextkonsumenten neu berechnet, was die Leistung beeinträchtigen kann.

useReducer — Komplexe Zustandslogik

useReducer ist eine Alternative zu useState für Zustände mit komplexer Aktualisierungslogik. Er nimmt eine Reducer-Funktion und einen Anfangszustand entgegen, gibt den aktuellen Zustand und eine Dispatch-Funktion zurück. Der Reducer erhält den aktuellen Zustand und eine Aktion, gibt einen neuen Zustand zurück — eine reine Funktion ohne Nebeneffekte.

useReducer ist besonders nützlich, wenn mehrere Aktionen (set, reset, increment, addItem) einen Zustand verwalten. Statt mehrerer useState mit verschiedenen Settern — ein Reducer mit klaren Aktionstypen. Dies macht die Logik vorhersagbar und leicht testbar.

js
import React, { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { ...state, count: state.count + 1 };
    case 'setStep':
      return { ...state, step: action.step };
    case 'reset':
      return { count: 0, step: 1 };
    default:
      throw new Error('Unknown action: ' + action.type);
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, {
    count: 0,
    step: 1
  });

  return (
    <>
      <p>Count: {state.count}</p>
      <button
        onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button
        onClick={() => dispatch({ type: 'reset' })}>Reset</button>
    </>
  );
}

useRef, useMemo, useCallback — Optimierung

useRef erzeugt ein veränderbares Objekt, das zwischen Renderings bestehen bleibt. Das Ändern von current löst kein erneutes Rendern aus. Hauptanwendungen sind der Zugriff auf DOM-Elemente und die Speicherung veränderbarer Werte (Timer, vorherige Werte, Bibliotheksinstanzen).

useMemo merkt sich das Ergebnis einer Funktion. Es berechnet den Wert nur neu, wenn sich eine Abhängigkeit ändert. Verwenden Sie es für teure Berechnungen — Filtern großer Arrays, Sortieren, Datenformatierung. useCallback ist ein Spezialfall von useMemo zum Merken von Funktionen.

js
import React, { useRef, useMemo, useCallback } from 'react';

function SearchPage({ items, query, onItemSelect }) {
  const inputRef = useRef(null);

  // Autofokus bei Montage
  useEffect(() => {
    inputRef.current?.focus();
  }, []);

  // Gefiltertes Ergebnis merken
  const filtered = useMemo(() => {
    return items.filter(item =>
      item.name.toLowerCase()
        .includes(query.toLowerCase())
    );
  }, [items, query]);

  // Callback merken
  const handleSelect = useCallback((id) => {
    onItemSelect(id);
  }, [onItemSelect]);

  return (
    <div>
      <input ref={inputRef}
        value={query}
        onChange={e => setQuery(e.target.value)}
      />
      <ul>
        {filtered.map(item =>
          <li key={item.id}>
            <button
              onClick={() => handleSelect(item.id)}>
              {item.name}
            </button>
          </li>
        )}
      </ul>
    </div>
  );
}

Eine wichtige Regel: useRef, useMemo und useCallback sind Optimierungswerkzeuge, keine zwingenden Konstrukte. Wickeln Sie nicht alles in useMemo — messen Sie zuerst die Leistung. Vorzeitige Optimierung verkompliziert den Code. React rendert Komponenten schnell; useMemo wird nur benötigt, wenn Berechnungen wirklich teuer sind (O(n²) und höher).

Hook-Regeln und häufige Fehler

React führte zwei strenge Regeln für Hooks ein. Erstens: Rufen Sie Hooks nur auf der obersten Ebene auf — nicht innerhalb von Bedingungen, Schleifen oder verschachtelten Funktionen. Zweitens: Rufen Sie Hooks nur aus funktionalen React-Komponenten oder benutzerdefinierten Hooks auf. Das ESLint-Plugin eslint-plugin-react-hooks überprüft beide Regeln automatisch.

Der häufigste Fehler ist die Verletzung der Aufrufreihenfolge von Hooks. React verlässt sich auf die Reihenfolge der Hook-Aufrufe zwischen Renderings. Wenn ein Hook innerhalb einer Bedingung steht und bei einem Rendering nicht ausgeführt wird, verschieben sich alle nachfolgenden Hooks, was Fehler verursacht.

FehlerWas passiertLösung
Hook in BedingungHook-Reihenfolge brichtBedingungslogik in den Hook verschieben
Stale closureEffekt verwendet alten WertAlle Abhängigkeiten zum Array hinzufügen
EndlosschleifeuseEffect ohne Abhängigkeiten ändert StateAbhängigkeiten angeben oder useReducer verwenden
Ref-Änderung während RenderNebeneffekt im FunktionskörperMutationen in useEffect verschieben

Der zweite häufige Fehler ist Stale Closure in useEffect. Wenn der Effekt eine Variable verwendet, die nicht in den Abhängigkeiten angegeben ist, „erfasst“ der Effekt ihren Wert zum Zeitpunkt der Closure-Erstellung. Die Lösung ist, alle verwendeten Variablen immer in das Abhängigkeitsarray aufzunehmen. Bei zu vielen Abhängigkeiten sollten Sie den Effekt in mehrere aufteilen.

Häufig gestellte Fragen

Warum dürfen Hooks nicht innerhalb von Bedingungen aufgerufen werden?

React verlässt sich auf die Reihenfolge der Hook-Aufrufe zwischen Renderings. Wenn ein Hook innerhalb einer Bedingung aufgerufen wird und bei einem Rendering nicht ausgelöst wird, verschieben sich alle nachfolgenden Hooks — ihr Zustand wird durcheinandergebracht. Die ESLint-Regel hooks/exhaustive-deps warnt davor.

Was ist der Unterschied zwischen useEffect und useLayoutEffect?

useLayoutEffect ist synchron und wird ausgeführt, bevor der Browser Änderungen malt. useEffect ist asynchron — nach dem Malen. Verwenden Sie useLayoutEffect nur, wenn Sie DOM messen oder ändern müssen, bevor der Benutzer die Änderungen sieht (Popover-Position, Scroll-Wiederherstellung).

Wie bricht man eine Fetch-Anfrage beim Unmount ab?

Verwenden Sie AbortController innerhalb von useEffect. Erstellen Sie einen Controller, übergeben Sie das Signal an fetch und rufen Sie controller.abort() in der Bereinigungsfunktion auf. Für ältere Browser verwenden Sie ein cancelled-Flag: return () => { cancelled = true; } mit einer Überprüfung vor setState.

Was ist ein benutzerdefinierter Hook und wann wird er erstellt?

Ein benutzerdefinierter Hook ist eine JavaScript-Funktion mit dem Präfix use, die eingebaute Hooks verwendet. Erstellen Sie einen, wenn dieselbe Logik mit Hooks in zwei oder mehr Komponenten wiederholt wird. Beispiele: useDebounce, useLocalStorage, useMediaQuery. Benutzerdefinierte Hooks ersetzen HOC und render props.

Warum wird useEffect im Strict Mode zweimal ausgeführt?

Im Strict Mode mountet und unmountet React die Komponente in der Entwicklung absichtlich zweimal, um Fehler mit ungereinigten Effekten zu finden. Wenn die Bereinigung korrekt geschrieben ist, verursacht der doppelte Aufruf keine Probleme. Im Produktionsmodus passiert dies nicht.

Zusammenfassung

  • React Hooks — Funktionen zur Verwendung von State, Effekten und Context in funktionalen Komponenten, die Klassen ersetzen.
  • useState — grundlegender Hook für lokalen Zustand mit funktionalem Setter für sichere Aktualisierungen.
  • useEffect — universeller Hook für Nebeneffekte mit Abhängigkeitsarray und Bereinigungsfunktion.
  • useContext — direkter Zugriff auf den React-Kontext ohne Consumer-Wrapper und zusätzliche Verschachtelung.
  • useReducer — für komplexe Zustandslogik mit Aktionstypen, eine Alternative zu Redux innerhalb einer einzelnen Komponente.
  • useRef, useMemo, useCallback — Optimierungswerkzeuge: DOM-Referenzen, Merken von Werten und Callbacks.
  • Top-Level-Regel — strenge Einschränkung, Hooks außerhalb von Bedingungen, Schleifen und verschachtelten Funktionen aufzurufen.

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch