Hirefullstack – Software Engineering & IT-Beratung aus Berlin
← Zur Übersicht
Kern 11 Min Lesezeit

useContext

Einen Wert nach unten durchreichen, ohne jede Zwischenstation zu nerven

In einem Satz

Context ist eine Rohrpost durch deine Komponenten: oben etwas hineinlegen, unten überall herausnehmen – ohne es durch fünf Ebenen als Prop weiterzugeben.

Das Problem hat einen Namen: Prop DrillingWenn ein Wert durch mehrere Komponenten durchgereicht wird, die ihn selbst gar nicht brauchen.. Du willst das Theme von ganz oben bis zum Button ganz unten bringen – und musst es durch vier Komponenten reichen, die es selbst gar nicht brauchen. Genau das löst Context. Und nichts anderes.

Bildlich gesprochen

Props sind wie von Hand weiterreichen: jede Person in der Kette muss das Paket anfassen. ContextEine Art Rohrpost: Ein Wert wird oben eingelegt und kann überall weiter unten herausgeholt werden. ist die Rohrpost: einmal oben einwerfen, unten kommt es an – die Ebenen dazwischen merken nichts davon.

Drei Schritte

theme.tsx
import { createContext, useContext, useState } from "react";

// 1) Die Rohrpost anlegen
const ThemeContext = createContext<Theme | null>(null);

// 2) Oben etwas hineinlegen
function App() {
  const [mode, setMode] = useState("hell");
  const wert = { mode, umschalten: () => setMode(m => m === "hell" ? "dunkel" : "hell") };

  return (
    <ThemeContext.Provider value={wert}>
      <GanzeSeite />
    </ThemeContext.Provider>
  );
}

// 3) Unten herausnehmen – egal wie tief
function Button() {
  const theme = useContext(ThemeContext);
  return <button onClick={theme.umschalten}>{theme.mode}</button>;
}
Tipp Bau dir immer einen eigenen Hook drumherum

Statt an 30 Stellen useContext(ThemeContext) zu schreiben, schreibst du einmal useTheme(). Vorteil: Die Prüfung „gibt es überhaupt einen Provider?“ steht an einer Stelle, und du kannst innen später alles umbauen.

eigener-hook.ts
export function useTheme() {
  const wert = useContext(ThemeContext);
  if (!wert) throw new Error("useTheme braucht einen <ThemeProvider> darüber");
  return wert;
}

Wichtig: Context speichert nichts

Context transportiert nur. Der State lebt weiterhin in einem ganz normalen useState in der Komponente, die den ProviderDie Komponente, die einen Context-Wert bereitstellt. Alles, was in ihr steckt, kommt an den Wert heran. rendert. Context ersetzt also keinen State-Manager wie Redux – es ersetzt das Durchreichen von Props.

Nimm es, wenn …
  • +

    Theme, Sprache, Formatierung

  • +

    Wer ist angemeldet und was darf die Person

  • +

    Werte innerhalb einer Komponentenfamilie (<Tabs><Tab>)

  • +

    Kurz: Dinge, die selten wechseln und die viele brauchen

Lass es, wenn …
  • Werte, die sich ständig ändern (Mausposition, jeder Tastendruck)

  • Als Zwischenspeicher für Serverdaten – dafür gibt es fertige Bibliotheken

  • Um zwei Ebenen Props zu sparen – dann ist die Prop einfacher

Die eine Falle: das Objekt ist jedes Mal neu

alle darunter zeichnen jedes Mal neu
function App() {
  const [user, setUser] = useState(null);

  // dieses Objekt ist bei JEDEM Zeichnen neu
  return (
    <UserContext.Provider value={{ user, setUser }}>
      <GroßerBaum />
    </UserContext.Provider>
  );
}
stabil, solange sich nichts ändert
function App() {
  const [user, setUser] = useState(null);

  const wert = useMemo(() => ({ user, setUser }), [user]);

  return (
    <UserContext.Provider value={wert}>
      <GroßerBaum />
    </UserContext.Provider>
  );
}

Jede Komponente, die den Context liest, zeichnet neu, sobald der Wert ein anderer ist – und ein frisch gebautes Objekt ist immer ein anderes. useMemo lernst du in der Lektion zu useMemo & useCallback kennen.

Genauer erklärt: Aufteilen, memo und Next.js optional
Tipp Selten und häufig trennen

Ein bewährtes Muster: zwei Contexts – einen für die Daten (user), einen für die Aktionen (logout, setUser). Der Aktions-Context ändert sich nie, deshalb zeichnen Komponenten, die nur Aktionen brauchen, gar nicht mit.

Wichtig zu wissen: React.memo hilft gegen Context-Updates nicht. Der Wert kommt nicht über Props herein, sondern an ihnen vorbei – die Prop-Prüfung sieht ihn also gar nicht.

Gut zu wissen In Next.js braucht der Provider "use client"

createContext und useContext funktionieren nur in einer Client-KomponenteEine Komponente, die im Browser läuft und deshalb State, Hooks und Klicks kann. Erkennbar an "use client" oben in der Datei.. Der Provider gehört also in eine Datei mit "use client" ganz oben. Server-Komponenten darfst du weiterhin als children hineinreichen – die laufen dann trotzdem auf dem Server.

Gut zu wissen React 19: Provider kürzer

Statt <ThemeContext.Provider value={…}> darfst du inzwischen <ThemeContext value={…}> schreiben. Beides funktioniert.

Sitzt das schon?

4 Fragen zu dieser Lektion. Falsche Antworten landen in deiner Statistik.

Jetzt selbst schreiben

Durchreichen abschaffen

mode und umschalten werden durch drei Ebenen gereicht, obwohl nur die unterste sie braucht. Ersetze das durch einen Context mit eigenem Hook useTheme().

  • Toolbar und Panel nehmen keine Props mehr entgegen
  • ThemedButton holt sich alles über useTheme()
  • Ein Klick schaltet zwischen hell und dunkel um
import { createContext, useContext, useState } from "react";

// TODO: Context anlegen und einen useTheme()-Hook bauen

function ThemedButton({ mode, umschalten }: any) {
  return (
    <button onClick={umschalten} data-testid="btn">
      Modus: {mode}
    </button>
  );
}

function Panel({ mode, umschalten }: any) {
  return <ThemedButton mode={mode} umschalten={umschalten} />;
}

function Toolbar({ mode, umschalten }: any) {
  return <Panel mode={mode} umschalten={umschalten} />;
}

export default function App() {
  const [mode, setMode] = useState("hell");
  const umschalten = () => setMode((m) => (m === "hell" ? "dunkel" : "hell"));

  return (
    <div style={{ fontFamily: "system-ui", padding: 16 }}>
      <Toolbar mode={mode} umschalten={umschalten} />
    </div>
  );
}

Hirefullstack

Ihr braucht React-Verstärkung im Team?

Wir bauen seit Jahren React- und Next.js-Anwendungen für Kunden in ganz Deutschland – als einzelner Experte, als Verstärkung fürs Bestandsteam oder als komplettes Scrum-Team.

Projekt besprechen →