Hooks sind spezielle Funktionen, mit denen Function-Components Features bekommen, die früher Klassen-Components vorbehalten waren: lokaler State, Side-Effects, Refs, Context, Performance-Optimierungen. Sie wurden 2018 mit React 16.8 eingeführt und haben Klassen-Components in praktisch allen neuen Codebases verdrängt. Hooks beginnen per Konvention mit use (useState, useEffect, useRef) und folgen zwei harten Hook-Regeln: nur auf der Top-Ebene einer Komponente aufrufen, nie in Schleifen oder Bedingungen — und nur in React-Components oder anderen Hooks, nie in normalen Funktionen.

Was sind Hooks?

Ein Hook ist eine Funktion, die React-interne Mechanismen nutzt — typischerweise um etwas zwischen Renders zu speichern oder Side-Effects auszulösen. Die Komponente selbst läuft bei jedem Render neu, aber der Hook „erinnert" sich an seinen Zustand.

TypeScript WasIstEinHook.jsx
import { useState, useEffect } from 'react';

const Counter = () => {
    const [count, setCount] = useState(0);   // State-Hook

    useEffect(() => {                         // Side-Effect-Hook
        document.title = `Klicks: ${count}`;
    }, [count]);

    return (
        <button onClick={() => setCount(c => c + 1)}>
            Klicks: {count}
        </button>
    );
};

useState speichert count über Re-Renders hinweg. useEffect führt nach jedem Render mit geändertem count einen Side-Effect aus. Beides funktioniert nur, weil React sich pro Komponente merkt, welcher Hook welchen Wert hat.

Die zwei Hook-Regeln

Regel 1: Nur auf der Top-Ebene

Hooks müssen immer in derselben Reihenfolge und Anzahl aufgerufen werden. Dadurch kann React sie intern korrekt zuordnen.

TypeScript HookRegeln.jsx
// FALSCH — bedingter Hook-Aufruf
const Broken = ({ enabled }) => {
    if (enabled) {
        const [count, setCount] = useState(0);  // FEHLER
    }
    return <p>Hi</p>;
};

// FALSCH — Hook in Schleife
const BrokenLoop = ({ items }) => {
    for (const item of items) {
        const [x, setX] = useState(0);  // FEHLER
    }
};

// RICHTIG — Top-Level, immer aufgerufen
const Fixed = ({ enabled }) => {
    const [count, setCount] = useState(0);
    if (!enabled) return null;
    return <p>{count}</p>;
};

Daher sind Hooks niemals in if, for, while, try/catch oder nach einem Early-Return erlaubt. Bedingte Logik gehört INNERHALB des Hook-Callbacks oder als Verzweigung im JSX.

Regel 2: Nur in React-Funktionen

Hooks dürfen aufgerufen werden in:

  • React-Function-Components (mit PascalCase-Namen)
  • Custom Hooks (Funktionen, deren Name mit use beginnt)

Nicht erlaubt in: normalen Funktionen, Klassen-Components, Event-Handlern, Promise-Callbacks, asynchronen Funktionen.

TypeScript WoHooksErlaubt.jsx
// FALSCH — kein Component, kein Custom Hook
function helper() {
    const [x] = useState(0);   // FEHLER
}

// RICHTIG — Custom Hook (Name beginnt mit `use`)
function useCounter(start = 0) {
    const [count, setCount] = useState(start);
    return [count, () => setCount(c => c + 1)];
}

// RICHTIG — Function-Component
function App() {
    const [count, inc] = useCounter(0);
    return <button onClick={inc}>{count}</button>;
}

Der Linter eslint-plugin-react-hooks mit der Regel rules-of-hooks erkennt Verstöße zuverlässig.

Eingebaute Hooks im Überblick

HookZweck
useStateLokaler veränderbarer State pro Komponente
useEffectSide-Effects nach dem Render (Fetch, Subscribe, DOM)
useLayoutEffectWie useEffect, aber synchron vor dem Browser-Paint
useRefMutable Container für DOM-Knoten oder Werte ohne Re-Render
useMemoWert memoisieren, nur neu berechnen bei Dependency-Änderung
useCallbackFunktion memoisieren, stabile Referenz für React.memo-Kinder
useContextContext-Wert lesen ohne Prop-Drilling
useReducerKomplexen State mit Actions verwalten (Redux-Style local)
useImperativeHandleSelektives API für Parent-Components via ref
useTransitionUpdates als „nicht dringend" markieren (Concurrent)
useDeferredValueWert mit Verzögerung übernehmen (verhindert UI-Stockungen)
useIdEindeutige IDs für a11y-Attribute (SSR-kompatibel)
useSyncExternalStoreExterne Stores (Redux, Zustand) sicher subscriben
useOptimisticOptimistische UI-Updates (React 19)
useActionStateForm-Actions mit State-Update (React 19)

Dazu kommen die selteneren useDebugValue (für React DevTools) und useInsertionEffect (für CSS-in-JS-Libraries).

Custom Hooks

Eigene Hooks sind Funktionen, die andere Hooks aufrufen und wiederverwendbare Logik bündeln. Konvention: der Name beginnt mit use.

TypeScript useLocalStorage.js
import { useState, useEffect } from 'react';

function useLocalStorage(key, initial) {
    const [value, setValue] = useState(() => {
        const stored = localStorage.getItem(key);
        return stored ? JSON.parse(stored) : initial;
    });

    useEffect(() => {
        localStorage.setItem(key, JSON.stringify(value));
    }, [key, value]);

    return [value, setValue];
}

// Verwendung
const Theme = () => {
    const [theme, setTheme] = useLocalStorage('theme', 'light');
    return <button onClick={() => setTheme(t => t === 'light' ? 'dark' : 'light')}>{theme}</button>;
};

Custom Hooks haben die gleichen Regeln wie eingebaute — Top-Level, in Components oder anderen Hooks. Der use-Prefix ist nicht nur Konvention, sondern wird vom Linter zur Hook-Erkennung genutzt.

Hooks vs. Class-Lifecycles

Class-LifecycleHook-Äquivalent
componentDidMountuseEffect(..., [])
componentDidUpdateuseEffect(..., [deps])
componentWillUnmountReturn-Funktion in useEffect
getDerivedStateFromPropsmeist überflüssig — einfach im Render rechnen
shouldComponentUpdateReact.memo + useMemo/useCallback
this.state / setStateuseState / useReducer

Der wichtigste Unterschied: Class-Lifecycles waren zeitlich organisiert (mount, update, unmount). Hooks sind konzeptuell organisiert (State, Effect, Memo) — ein Effect kann sowohl beim Mount als auch bei jedem Update laufen, abhängig vom Dependency-Array.

Interessantes

Hooks beginnen mit use — das ist Pflicht für den Linter.

Der ESLint-Linter eslint-plugin-react-hooks erkennt Hooks am use-Prefix. Eigene Funktionen, die Hooks intern nutzen, MÜSSEN ebenfalls mit use beginnen — sonst warnt der Linter nicht bei Verstößen gegen Hook-Regeln.

Hook-Reihenfolge ist heilig — gleicher Aufruf, gleicher Index.

React identifiziert Hook-Werte intern per Aufruf-Reihenfolge, nicht per Name. Wenn die Reihenfolge zwischen Renders wechselt (durch bedingte Aufrufe), gibt es Daten-Korruption. Daher: Hooks IMMER am Anfang, IMMER vollständig, IMMER in gleicher Reihenfolge.

Hooks in Production-Builds laufen genauso wie in Development.

Anders als manche andere React-Features (StrictMode-Double-Render, dev-only Warnings) verhalten sich Hooks in Production identisch. Was im Dev funktioniert, funktioniert auch im Build — und umgekehrt.

Hooks sind die Antwort auf 'wie wiederverwendet man Logik?'

Vor Hooks gab es Render Props, HOCs, Mixins — alle mit ihren eigenen Problemen (Wrapper-Hell, Prop-Collisions, ungenauer this-Kontext). Custom Hooks lösen das elegant: Logik als Funktion, ohne Komponenten-Verschachtelung.

Hooks in async-Funktionen oder Callbacks — nicht erlaubt.

setTimeout(() => useState(0)) oder async function() { useState(0) } verletzen die Hook-Regeln. Hooks müssen synchron im Komponenten-Body laufen. Wer State asynchron setzen will: synchron useState aufrufen, im Effect/Handler den Setter aufrufen.

React DevTools zeigen alle Hooks einer Komponente.

Im React-DevTools-Panel ist pro Komponente sichtbar, welche Hooks aufgerufen wurden und welche Werte sie halten. Hilfreich beim Debuggen — vor allem bei verschachtelten Custom Hooks.

Class-Components funktionieren weiter, aber neue Features sind hook-only.

Suspense für Daten-Laden, useTransition, useOptimistic, Server-Components — alle nur in Function-Components nutzbar. Wer in Class-Code arbeitet, ist von den modernen React-Konzepten abgeschnitten.

useEffect ist NICHT immer der richtige Hook.

Häufige Fehlanwendung: useEffect für abgeleitete Werte, für Event-Handler-ähnliche Logik, für Daten-Initialisierung aus Props. Faustregel: useEffect nur für Synchronisation mit der Außenwelt (DOM, Network, Subscriptions). Alles andere lässt sich oft direkter lösen.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Hooks

Zur Übersicht