React State

React Context API

Die Context API ist der integrierte Weg von React, um State über einen Komponentenbaum zu teilen, ohne Props durch jede Ebene reichen zu müssen. Richtig eingesetzt, eliminiert sie Prop Drilling; unvorsichtig genutzt, führt sie zu unnötigen Re-Renders der gesamten App.

intermediate13 min readUpdated 15. Sept. 2026
ThemeContext.jsx
jsx
// ThemeContext.jsx
import { createContext, useContext } from "react";

const ThemeContext = createContext("light");

export function useTheme() {
  return useContext(ThemeContext);
}

export function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}
Enthalten in
React
Zusätzliche Pakete
Keine
Erstellt mit
createContext
Bereitgestellt durch
Context.Provider
Ausgelesen mit
useContext
Ideal für
Selten geänderte, geteilte Werte

Warum es wichtig ist

Warum Context existiert

Kein Prop Drilling

Jede Komponente im Baum kann einen geteilten Wert direkt lesen, unabhängig davon, wie tief sie verschachtelt ist.

Null Abhängigkeiten

Context ist Teil von React, sodass nichts installiert werden muss und keine zusätzliche Runtime berücksichtigt werden muss.

Komponierbare Provider

Du kannst mehrere Provider verschachteln und einen großen Wert in fokussierte Contexts aufteilen, um die Performance zu verbessern.

Das Gesamtbild

Die drei Säulen von Context

Ein Context-Objekt, ein Provider, der einen Wert bereitstellt, und ein Hook, der diesen liest. Mehr gibt es nicht zu lernen.

Das Context-Objekt

Identität

Einmal mit createContext erstellt, dient es als Schlüssel, mit dem Komponenten einen Provider finden.

Der Provider

Bereitstellung

Eine Komponente, die einen Wert in den Baum einspeist und Consumer bei Änderungen neu rendert.

Der Consumer

Auslesen

useContext liest den Wert des nächsten Providers aus; ein Custom Hook kapselt dies oft für eine bessere Bedienbarkeit.

Context auf einen Blick

Der Kern von Context

createContext

Definiert einen Context mit einem Standardwert, der verwendet wird, wenn kein Provider vorhanden ist.

Provider

Umschließt einen Teilbaum und gibt den aktuellen Wert an jeden darunterliegenden Consumer weiter.

useContext

Liest den Wert des nächstgelegenen Providers innerhalb einer beliebigen Komponente aus.

Custom Hooks

Kapselt useContext in einem Hook, damit Aufrufer eine klare API und Fehlerprüfungen erhalten.

Contexts aufteilen

Trennung von State und Actions, sodass Consumer nur für das neu rendern, was sie tatsächlich nutzen.

Performance

Context rendert bei Änderungen alle Consumer neu; halte Werte daher stabil und fokussiert.

Eine kurze Geschichte

Von der versteckten API zum First-Class Feature

  1. 2018

    Context wird stabil

    React 16.3 führt eine unterstützte Context API ein, nachdem jahrelang eine experimentelle Version existierte.

    18
  2. 2019

    Hooks erscheinen

    useContext macht das Konsumieren von Context zu einem Einzeiler und ersetzt Render Props.

    19
  3. 2021

    Context und Performance

    Die Community einigt sich auf das Aufteilen von Contexts und das Memoizing von Werten als Best Practice.

    21
  4. Heute

    Ein integriertes Werkzeug

    Context ist der Standard für Themes, Auth und Locale, während Stores hochfrequenten State verwalten.

    Heute

Der vollständige Leitfaden

React Context API: Alles was Sie wissen müssen

Was ist die Context API?

Die Context API ist die integrierte Lösung von React, um Daten durch einen Komponentenbaum zu reichen, ohne Props durch jede einzelne Ebene schleifen zu müssen. Sie löst ein spezifisches, häufig auftretendes Problem: ein Wert wird von vielen Komponenten benötigt, befindet sich aber weit über ihnen im Baum.

Das klassische Beispiel ist das Theming. Eine Button tief im Baum benötigt das aktuelle Theme, aber jede Komponente zwischen der obersten Ebene und dem Button müsste eine theme Prop akzeptieren und weiterreichen. Das nennt man Prop Drilling, und Context eliminiert genau das. Du stellst den Wert einmal bereit, und jeder Nachfahre kann ihn direkt auslesen.

Kontext erstellen und bereitstellen

Ein Kontext besteht aus drei Teilen: einem Objekt, einem Provider und einem Consumer-Hook.

// AuthContext.jsx
import { createContext, useContext, useMemo, useState } from "react";

const AuthContext = createContext(null);

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);

  const value = useMemo(
    () => ({
      user,
      login: (nextUser) => setUser(nextUser),
      logout: () => setUser(null),
    }),
    [user],
  );

  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

export function useAuth() {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error("useAuth must be used within an AuthProvider");
  }
  return context;
}

createContext definiert den Kontext und einen Standardwert. Der Provider stellt den aktuellen Wert für alle darunterliegenden Komponenten bereit. Der benutzerdefinierte Hook liest den Wert aus und gibt eine klare Fehlermeldung aus, falls die Komponente außerhalb des Providers verwendet wird.

Context konsumieren

Jeder Descendant kann den Wert lesen, unabhängig davon, wie tief er im Baum sitzt.

// Header.jsx
import { useAuth } from "./AuthContext";

export function Header() {
  const { user, logout } = useAuth();

  return (
    <header>
      <span>{user ? `Hi, ${user.name}` : "Guest"}</span>
      {user && <button onClick={logout}>Sign out</button>}
    </header>
  );
}

Die Header hat niemals ein Prop von App erhalten. Sie hat stattdessen direkt im Baum nach dem benötigten Wert gesucht, wodurch Zwischenkomponenten nichts von Daten erfahren, die sie nicht selbst verwenden.

Context ist kein State

Diese Unterscheidung führt oft zu Verwirrung. Context hält keinen State und verwaltet keine Updates. Er transportiert lediglich einen Wert. Der State selbst lebt in useState oder useReducer, und der Provider reicht ihn nach unten weiter.

Aus diesem Grund ist es ein gängiges Pattern, Context mit einem Reducer zu kombinieren:

// CartContext.jsx
import { createContext, useContext, useReducer } from "react";

const CartContext = createContext(null);

function reducer(state, action) {
  switch (action.type) {
    case "add":
      return [...state, action.item];
    case "remove":
      return state.filter((item) => item.id !== action.id);
    default:
      return state;
  }
}

export function CartProvider({ children }) {
  const [items, dispatch] = useReducer(reducer, []);
  return (
    <CartContext.Provider value={{ items, dispatch }}>
      {children}
    </CartContext.Provider>
  );
}

export const useCart = () => useContext(CartContext);

Der Reducer sorgt dafür, dass Updates vorhersehbar bleiben, und Context stellt sie überall zur Verfügung, ohne dass Prop Drilling nötig ist.

Performance: die eigentliche Einschränkung

Wenn sich der Wert eines Providers ändert, rendert jede Komponente, die diesen Context liest, neu. Es gibt keine Selektoren, weshalb man sich nicht nur auf einen Teil des Wertes abonnieren kann. Zwei Gewohnheiten helfen dabei, dies handhabbar zu halten.

Memoisiere den Wert. Ein Objekt-Literal erzeugt bei jedem Render-Vorgang eine neue Referenz. Das bedeutet, dass jeder Consumer neu rendert, selbst wenn sich inhaltlich nichts geändert hat.

// memoised
const value = useMemo(() => ({ user, logout }), [user]);

Teile Contexts auf. Platziere State und Actions in separaten Contexts oder teile sie nach Features auf. So rendert eine Komponente, die nur eine Action auslösen muss, nicht neu, wenn sich der State ändert.

// split.jsx
const CartStateContext = createContext(null);
const CartActionsContext = createContext(null);

Komponenten, die nur Actions aufrufen, abonnieren den Actions-Context. Da dessen Identität sich nie ändert, rendern diese Komponenten bei einem State-Update niemals neu. Dieser eine Trick löst die meisten Performance-Probleme im Zusammenhang mit Context.

Wann man Context verwenden sollte – und wann nicht

Context ist das richtige Werkzeug für:

  • Themes und Farbmodi.
  • Den authentifizierten Benutzer und die Session.
  • Locale und Übersetzungen.
  • Einen Router oder eine kleine, stabile Konfiguration.

Greifen Sie zu einem dedizierten Store, wenn Sie Folgendes haben:

  • Häufige Updates, wie beim Tippen, Drag-and-Drop oder bei Animationen.
  • Einen großen State-Tree, bei dem Komponenten Selektoren benötigen.
  • Einen Bedarf an middleware, Persistenz oder Time-Travel-Devtools.
  • Server-State, der Caching und Refetching erfordert.

Bibliotheken wie Zustand und Redux Toolkit bieten Selektoren an, sodass Komponenten nur Slices statt des gesamten Wertes abonnieren. Für Server-Daten übernimmt TanStack Query das gesamte Caching.

Best Practices

  • Kapseln Sie useContext in einem Custom Hook und prüfen Sie, ob ein Provider fehlt.
  • Memoisieren Sie Provider-Werte mit useMemo.
  • Trennen Sie Kontexte nach Zuständigkeiten, insbesondere State von Actions.
  • Halten Sie Kontext-Werte klein und fokussiert.
  • Verwenden Sie useReducer, wenn Updates komplex sind oder vom vorherigen State abhängen.
  • Verwenden Sie Kontext nicht für hochfrequente Updates; nutzen Sie stattdessen einen selector-basierten Store.
  • Definieren Sie sinnvolle Standardwerte, damit Komponenten bei Bedarf auch außerhalb eines Providers rendern können.

Häufige Fehler

  • Context als State-Manager zu behandeln und Selektoren zu erwarten.
  • Ein Inline-Objekt als Provider-Value zu übergeben, was zu Re-Renders aller Komponenten führt.
  • Nicht zusammengehörige Daten in einem einzigen, riesigen Context zu bündeln.
  • Den Default-Wert zu vergessen, was zu einem Absturz bei undefined führt.
  • Context für Werte zu verwenden, die nur von ein oder zwei Komponenten benötigt werden.
  • Zu erwarten, dass Context Re-Renders automatisch optimiert.

Wie geht es weiter?

Context ist das Fundament für das Teilen von State in React. Wenn man seine Grenzen kennt, weiß man, wann es Zeit für den nächsten Schritt ist. Vergleiche es mit Redux Toolkit für vorhersagbaren State in großen Anwendungen und Zustand für einen leichtgewichtigen Selector-Store. Für die Verwaltung von Server-Daten empfiehlt sich TanStack Query. In Vue wird das entsprechende Konzept im Pinia-Guide behandelt.

Werte teilen

Context ist für Werte gedacht, die viele Komponenten benötigen, wie z. B. das Theme oder der aktuelle Benutzer. Er ist kein Ersatz für jede einzelne Prop.

Bevorzugt
const ThemeContext = createContext("light");

function Button() {
  const theme = useContext(ThemeContext);
  return <button className={theme} />;
}
Vermeiden
function Button({ theme }) {
  return <button className={theme} />;
}
// drilled through every
// level of the tree

Werte bereitstellen

Ein Inline-Objekt erzeugt bei jedem Render einen neuen Referenzwert, was jeden Consumer neu rendert. Nutze Memoization.

Bevorzugt
const value = useMemo(
  () => ({ user, logout }),
  [user],
);

<AuthContext.Provider value={value}>
  {children}
</AuthContext.Provider>
Vermeiden
<AuthContext.Provider
  value={{ user, logout }}
>
  {children}
</AuthContext.Provider>

Häufig gestellte Fragen

Häufig gestellte Fragen

Keep learning

Related topics from the roadmap.

$ Lernen Sie jetzt

Bereit, Context API zu lernen?

Unser interaktives Tutorial führt Sie Schritt für Schritt durch Context API — mit Quizzen und echtem Code, den Sie im Browser ausführen können.