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 →