Zurück zur Startseite

So verwenden Sie React Hooks: Vollständiger Leitfaden mit Beispielen

Dieser umfassende Leitfaden lehrt Entwickler, wie sie React-Hooks effektiv in modernen React-Anwendungen einsetzen. Er behandelt wesentliche integrierte Hooks wie useState und useEffect, erklärt die Regeln für Hooks, bietet Techniken zur Leistungsoptimierung mit useMemo und useCallback und demonstriert die Erstellung benutzerdefinierter Hooks mit praktischen Codebeispielen.

React Hooks Tutorial: Meistern Sie State & Effects im Jahr 2026
Advertisement 728x90

React Hooks verwenden: Eine vollständige Anleitung mit Beispielen

React Hooks verwenden: Eine vollständige Anleitung mit Beispielen

Als React 16.8 Anfang 2019 Hooks einführte, veränderte dies grundlegend, wie Entwickler React-Anwendungen erstellen, indem Funktionskomponenten nun Zustände, Seiteneffekte und Kontexte verwalten können, ohne Klassenkomponenten schreiben zu müssen. Das Verständnis, wie man React Hooks effektiv einsetzt, ist heute für jeden modernen React-Entwickler unerlässlich, da Hooks „die einzige Art und Weise sind, wie der Großteil des React-Codes geschrieben wird". Dieser Leitfaden führt Sie durch die wichtigsten integrierten Hooks, erklärt die Regeln, die sie bestimmen, und liefert praktische Beispiele, die Sie sofort anwenden können.

Was Sie lernen werden

Am Ende dieses Leitfadens werden Sie Reacts Kern-Hooks – useState, useEffect, useContext, useRef, useReducer, useMemo und useCallback – sicher in Ihren eigenen Projekten einsetzen. Sie verstehen, wann Sie welchen Hook wählen, wie Sie häufige Fallstricke wie unnötige Neurenderings vermeiden und wie Sie wiederverwendbare Logik in eigene Hooks auslagern. Die wichtigste Erkenntnis ist, dass Hooks nur Funktionen sind – zu lernen, wie man sie kombiniert, ist der Schlüssel zur Beherrschung von React.

Google AdInline article slot

Die Regeln der Hooks verstehen

Bevor wir uns den einzelnen Hooks widmen, müssen Sie zwei unverhandelbare Regeln kennen, die vom Paket eslint-plugin-react-hooks durchgesetzt werden:

  1. Rufe Hooks nur auf der obersten Ebene auf. Rufe Hooks niemals innerhalb von Schleifen, Bedingungen oder verschachtelten Funktionen auf. React verlässt sich auf die Reihenfolge, in der Hooks aufgerufen werden, um den Zustand zwischen den Renderings zu erhalten – wenn sich die Reihenfolge ändert, kann React den Zustand nicht korrekt seinem Hook zuordnen.

  2. Rufe Hooks nur aus React-Funktionen auf. Du darfst Hooks nur aus Funktionskomponenten oder aus anderen eigenen Hooks aufrufen. Eine normale JavaScript-Funktion kann useState oder useEffect nicht aufrufen.

    Google AdInline article slot

Aus der zweiten Regel ergibt sich eine Konvention: Jede Funktion, die Hooks aufruft, muss mit use beginnen (z. B. useCustomHook). Der Linter verwendet dieses Präfix, um die Regeln korrekt durchzusetzen.

Die wichtigsten Hooks für den täglichen Gebrauch

useState: Zustand einer Komponente verwalten

Der useState-Hook ist der grundlegendste Hook und ermöglicht es Ihnen, Funktionskomponenten einen Zustand hinzuzufügen. Er gibt ein Array mit zwei Elementen zurück: dem aktuellen Zustandswert und einer Funktion zum Aktualisieren.

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0); // Initialzustand ist 0
  
  return (
    <button onClick={() => setCount(count + 1)}>
      Geklickt {count} Mal
    </button>
  );
}

Wenn Sie den Zustand basierend auf dem vorherigen Wert aktualisieren, verwenden Sie die funktionale Update-Form, um Wettlaufsituationen zu vermeiden, insbesondere bei Reacts automatischem Batching:

Google AdInline article slot
// Sicher: verwendet den vorherigen Zustandswert
setCount(prevCount => prevCount + 1);

// Auch sicher für Objekte: spread des vorherigen Zustands
setUser(prevUser => ({ ...prevUser, name: 'Jane' }));

Wenn die Berechnung des Initialzustands aufwendig ist, übergeben Sie eine Funktion anstelle eines Werts – React führt diese nur beim ersten Rendern aus:

const [state, setState] = useState(() => {
  const initialState = someExpensiveComputation(props);
  return initialState;
});

useEffect: Seiteneffekte behandeln

Der useEffect-Hook ermöglicht es Ihnen, Seiteneffekte in Funktionskomponenten auszuführen, wie das Abrufen von Daten, das Einrichten von Abonnements oder das manuelle Ändern des DOM. Standardmäßig werden Effekte nach jedem abgeschlossenen Rendern ausgeführt, aber Sie können steuern, wann sie ausgelöst werden, indem Sie das Abhängigkeitsarray verwenden.

import { useEffect, useState } from 'react';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    // Dieser Effekt läuft nach dem Einhängen der Komponente und wenn sich userId ändert
    fetchUser(userId).then(data => setUser(data));
    
    // Optionale Bereinigungsfunktion läuft vor dem nächsten Effekt und beim Aushängen
    return () => {
      // Ausstehende Anfragen abbrechen oder Abonnements bereinigen
    };
  }, [userId]); // Abhängigkeitsarray: nur erneut ausführen, wenn sich userId ändert

  return <div>{user?.name}</div>;
}

Wichtige Muster für useEffect:

  • Leeres Abhängigkeitsarray []: Effekt läuft einmal nach dem initialen Rendern (Einhängen).
  • Kein Abhängigkeitsarray: Effekt läuft nach jedem Rendern (selten gewünscht).
  • Bereinigungsfunktion: Verhindert Speicherlecks durch Bereinigen von Abonnements, Timern oder ausstehenden Netzwerkanfragen.

Wichtiger Hinweis: Nicht jede Zustandsänderung erfordert einen Effekt. Wenn Sie einen Wert während des Renderings berechnen können, tun Sie dies direkt, anstatt useEffect zu verwenden:

// ❌ Unnötiger Effekt
const [fullName, setFullName] = useState('');
useEffect(() => {
  setFullName(`${firstName} ${lastName}`);
}, [firstName, lastName]);

// ✅ Direkt während des Renderings berechnen
const fullName = `${firstName} ${lastName}`;

useContext: Kontext ohne Prop Drilling nutzen

Der useContext-Hook ermöglicht es Ihnen, Werte aus dem React-Kontext zu lesen, ohne Ihre Komponente in eine Consumer-Komponente zu verpacken:

import { useContext } from 'react';

// Einen Kontext erstellen
const ThemeContext = React.createContext('light');

function ThemedButton() {
  // Kontextwert direkt lesen
  const theme = useContext(ThemeContext);
  return <button className={theme}>Klick mich</button>;
}

Wenn sich der Wert des Kontextanbieters ändert, wird jede Komponente, die useContext verwendet, automatisch neu gerendert.

useRef: Werte referenzieren, die keine Neurenderings auslösen

Der useRef-Hook erstellt ein veränderbares Ref-Objekt, dessen .current-Eigenschaft über Renderings hinweg bestehen bleibt. Anders als beim Zustand löst das Aktualisieren eines Refs kein Neurendern aus. Dies macht Refs ideal für:

  • Speichern von DOM-Element-Referenzen
  • Verfolgen von Timeout-IDs
  • Beibehalten von Werten, die keine UI-Updates auslösen sollen
import { useRef, useEffect } from 'react';

function TextInput() {
  const inputRef = useRef(null);

  useEffect(() => {
    // Eingabefeld nach dem Einhängen der Komponente fokussieren
    inputRef.current.focus();
  }, []);

  return <input ref={inputRef} type="text" />;
}

useReducer: Komplexe Zustandslogik verwalten

Für Zustände, die mehrere Unterwerte oder komplexe Übergänge umfassen, ist useReducer oft useState vorzuziehen. Es akzeptiert eine Reducer-Funktion und einen Initialzustand und gibt den aktuellen Zustand sowie eine Dispatch-Funktion zurück:

import { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    case 'reset':
      return { count: action.payload };
    default:
      return state;
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);
  
  return (
    <>
      Anzahl: {state.count}
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
      <button onClick={() => dispatch({ type: 'reset', payload: 0 })}>Zurücksetzen</button>
    </>
  );
}

Hooks zur Leistungsoptimierung

useMemo: Aufwendige Berechnungen zwischenspeichern

useMemo speichert das Ergebnis einer Berechnung zwischen und berechnet es nur neu, wenn sich die Abhängigkeiten ändern:

import { useMemo } from 'react';

function TodoList({ todos, filter }) {
  // Nur neu berechnen, wenn sich todos oder filter ändern
  const filteredTodos = useMemo(() => {
    return todos.filter(todo => todo.status === filter);
  }, [todos, filter]);

  return (
    <ul>
      {filteredTodos.map(todo => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
}

useCallback: Funktionsreferenzen memoieren

useCallback gibt eine gememoisierte Version einer Callback-Funktion zurück, die sich nur ändert, wenn sich die Abhängigkeiten ändern. Dies ist besonders nützlich, wenn Sie Callbacks an optimierte Kindkomponenten übergeben, die auf Referenzgleichheit angewiesen sind, um unnötige Neurenderings zu vermeiden:

import { useCallback } from 'react';

function ParentComponent() {
  const handleClick = useCallback(() => {
    console.log('Button geklickt');
  }, []); // Funktionsreferenz bleibt über Renderings hinweg stabil

  return <ChildButton onClick={handleClick} />;
}

Eigene Hooks: Logik über Komponenten hinweg wiederverwenden

Die wahre Stärke von Hooks zeigt sich, wenn Sie eigene Hooks erstellen, um zustandsbehaftete Logik zu extrahieren und wiederzuverwenden. Ein eigener Hook ist einfach eine JavaScript-Funktion, deren Name mit use beginnt und die andere Hooks aufrufen kann.

Beispiel: useLocalStorage

Dieser eigene Hook synchronisiert den Zustand mit localStorage und bewahrt Daten über Seitenneuladungen hinweg:

import { useState, useEffect } from 'react';

function useLocalStorage(key, initialValue) {
  const [value, setValue] = useState(() => {
    if (typeof window === 'undefined') return initialValue;
    const stored = localStorage.getItem(key);
    return stored !== null ? JSON.parse(stored) : initialValue;
  });

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

  return [value, setValue];
}

// Verwendung
function ThemeToggle() {
  const [theme, setTheme] = useLocalStorage('theme', 'light');
  return (
    <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
      Wechsel zu {theme === 'light' ? 'dunklem' : 'hellem'} Modus
    </button>
  );
}

Beispiel: useMediaQuery

Dieser Hook ermöglicht es Ihnen, Komponenten basierend auf CSS-Medienabfragen bedingt zu rendern, z. B. basierend auf der Benutzereinstellung für reduzierte Bewegung:

import { useState, useEffect } from 'react';

function useMediaQuery(query) {
  const [matches, setMatches] = useState(() => {
    if (typeof window === 'undefined') return false;
    return window.matchMedia(query).matches;
  });

  useEffect(() => {
    const mediaQueryList = window.matchMedia(query);
    const onChange = (event) => setMatches(event.matches);
    mediaQueryList.addEventListener('change', onChange);
    return () => mediaQueryList.removeEventListener('change', onChange);
  }, [query]);

  return matches;
}

// Verwendung
function MotionAwareComponent() {
  const prefersReducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)');
  return prefersReducedMotion ? <StaticHero /> : <AnimatedHero />;
}

React 19: Neue Hooks für Formulare und asynchrone Daten

React 19 (veröffentlicht im Dezember 2024) führte mehrere neue Hooks ein, die die Handhabung von Formularen und asynchronen Operationen vereinfachen.

useActionState: Formularübermittlung vereinfachen

useActionState verwaltet den Zustand der Formularübermittlung und gibt das letzte Ergebnis, eine Aktionsfunktion und ein pending-Flag zurück:

import { useActionState } from 'react';

async function subscribeAction(prevState, formData) {
  const email = formData.get('email');
  try {
    await subscribe(email);
    return { ok: true };
  } catch (error) {
    return { ok: false, error: error.message };
  }
}

function NewsletterForm() {
  const [state, formAction, isPending] = useActionState(
    subscribeAction,
    { ok: false }
  );

  return (
    <form action={formAction}>
      <input name="email" type="email" required />
      <button type="submit" disabled={isPending}>
        {isPending ? 'Abonnieren...' : 'Abonnieren'}
      </button>
      {state.ok && <p>Sie sind abonniert!</p>}
      {state.error && <p style={{ color: 'red' }}>{state.error}</p>}
    </form>
  );
}

useFormStatus: Zugriff auf den Zustand des übergeordneten Formulars

useFormStatus ermöglicht es verschachtelten Komponenten zu erfahren, ob ihr übergeordnetes Formular gerade übermittelt wird:

import { useFormStatus } from 'react';

function SubmitButton() {
  const { pending } = useFormStatus();
  return (
    <button type="submit" disabled={pending}>
      {pending ? 'Speichern...' : 'Speichern'}
    </button>
  );
}

Integration mit Redux: Der useSelector-Hook

Bei der Verwendung von Redux mit React ist der useSelector-Hook die moderne, empfohlene Methode, um auf den Zustand aus dem Redux-Store zuzugreifen. Er ersetzt die ältere connect-Higher-Order-Komponente und funktioniert besser mit TypeScript.

import { useSelector, useDispatch } from 'react-redux';

function CounterComponent() {
  // Bestimmte Daten aus dem Redux-Store extrahieren
  const count = useSelector((state) => state.counter.value);
  const dispatch = useDispatch();

  return (
    <div>
      <span>{count}</span>
      <button onClick={() => dispatch(increment())}>Erhöhen</button>
    </div>
  );
}

Wichtig: useSelector verwendet standardmäßig strikte ===-Referenzgleichheit. Jedes Mal ein neues Objekt zurückzugeben, erzwingt Neurenderings. Verwenden Sie gememoisierte Selektoren oder rufen Sie useSelector mehrmals für einzelne Felder auf, um die Leistung zu optimieren:

// ❌ Dies verursacht bei jeder Aktion Neurenderings
const { count, user } = useSelector((state) => ({
  count: state.count,
  user: state.user
}));

// ✅ useSelector für jedes Feld aufrufen
const count = useSelector((state) => state.count);
const user = useSelector((state) => state.user);

Quellen

  • React Offizielle Dokumentation: Integrierte React Hooks
  • React Offizielle Dokumentation: Hooks-API-Referenz
  • React Redux Dokumentation: Hooks-API
  • Patterns.dev: Hooks-Muster
  • React Offizielle Dokumentation: Den State-Hook verwenden

— Editorial Team

Advertisement 728x90

Weiterlesen