useContext ist ein React-Hook, der funktionalen Komponenten direkten Zugriff auf Daten aus einem über createContext erstellten Kontext bietet. Kontext in React löst das Problem des Props Drilling — der Weitergabe von Props durch viele zwischengeschaltete Komponenten, die diese Daten selbst nicht nutzen. Laut der React Documentation (2025) nimmt useContext ein Kontextobjekt entgegen und gibt den aktuellen Wert zurück, der vom nächsten Provider weiter oben im Komponentenbaum gesetzt wurde. Wenn sich der Wert im Provider ändert, werden alle Komponenten, die useContext verwenden, automatisch neu gerendert.
Wichtige Punkte
useContext ist ein Hook, der in React 16.8 zusammen mit anderen Hooks hinzugefügt wurde und das Lesen eines Wertes aus dem React-Kontext ermöglicht. Kontext ist ein in React eingebauter Mechanismus, der dazu dient, Daten durch den Komponentenbaum zu leiten, ohne Props auf jeder Ebene manuell übergeben zu müssen. useContext ersetzt die Consumer-Komponente der alten Context API und macht den Code prägnanter und lesbarer.
Typische Anwendungsfälle für Kontext umfassen Designs (hell/dunkel), Gebietsschema und Übersetzungen (i18n), Benutzerauthentifizierung, Anwendungseinstellungen und alle anderen globalen Daten, die viele Komponenten auf verschiedenen Verschachtelungsebenen benötigen. Das React-Team empfiehlt, Kontext für Daten zu verwenden, die für einen Teilbaum von Komponenten global sind, aber nicht für die gesamte Anwendung.
Laut React Team — Kontextdokumentation (2025) ist die falsche Verwendung von Kontext eine der Hauptursachen für Leistungsprobleme in React-Anwendungen. Jede Wertänderung im Provider führt zu einem Neurendern aller Konsumenten, unabhängig davon, welcher Teil der Daten sich geändert hat. Die Optimierung durch useMemo und die Aufteilung von Kontexten löst dieses Problem.
import { createContext, useContext } from 'react';
// Kontext mit Standardwert erstellen
const ThemeContext = createContext('hell');
function ThemedButton() {
const theme = useContext(ThemeContext);
return <button className={`btn-${theme}`}>Click</button>;
}
Der Kontextmechanismus in React wird durch das Provider-Consumer-Muster implementiert. createContext gibt ein Objekt mit zwei Entitäten zurück: Provider — eine Komponente, die den Wert weitergibt, und das Kontextobjekt selbst, das in useContext verwendet wird. Der Provider wird im Komponentenbaum montiert und gibt den Wert unabhängig von der Verschachtelungstiefe an alle Kindelemente weiter.
Wenn React auf einen useContext-Aufruf stößt, durchläuft es den Fiber-Baum auf der Suche nach dem nächsten Provider für diesen Kontext. Wenn ein Provider gefunden wird, wird dessen Wert zurückgegeben. Wenn kein Provider gefunden wird, wird der an createContext übergebene Standardwert zurückgegeben. Diese Suche erfolgt bei jedem Rendern, aber dank der Memoisierung von Fiber-Knoten ist sie sehr schnell und beeinträchtigt die Leistung nicht.
Laut React — Kontextinterna (2024) verwendet die interne Implementierung von useContext eine verknüpfte Liste von Hooks, ähnlich wie useState. Jeder Hook speichert einen Verweis auf einen Fiber-Knoten, sodass React schnell bestimmen kann, welcher Provider zu diesem Kontext gehört. Wenn ein Provider seinen Wert aktualisiert, markiert React alle Fiber-Knoten, die diesen Kontext verwenden, für das Neurendern.
Provider-Komponenten können ineinander verschachtelt werden, wodurch eine Hierarchie von Kontexten entsteht. Jeder untergeordnete Provider überschreibt den Wert des übergeordneten für seinen eigenen Teilbaum. Dies ist nützlich, wenn ein Bildschirm ein helles Design benötigt, während ein verschachteltes modales Fenster ein dunkles Design benötigt. useContext gibt immer den Wert des nächsten Providers weiter oben im Baum zurück.
const UserContext = createContext(null);
const ThemeContext = createContext('hell');
function App() {
return (
<UserContext.Provider value={{ name: 'Alice' }}>
<ThemeContext.Provider value='dark'>
<Profile />
</ThemeContext.Provider>
</UserContext.Provider>
);
}
Die Funktion createContext(defaultValue) erstellt ein Kontextobjekt. Der Parameter defaultValue wird verwendet, wenn eine Komponente useContext aufruft, aber kein entsprechender Provider weiter oben im Baum vorhanden ist. Ohne defaultValue gibt useContext undefined zurück, was zu unerwarteten Fehlern führen kann. Es wird empfohlen, immer einen sinnvollen Standardwert oder null zu übergeben.
Das Erstellen eines benutzerdefinierten Providers ist ein gängiges Muster zur Kapselung der Kontextlogik. Innerhalb eines solchen Providers wird der Zustand (über useState oder useReducer) gespeichert und über die value-Prop des Providers bereitgestellt. Dies verbirgt Implementierungsdetails vor den Konsumentenkomponenten und zentralisiert die Kontextverwaltungslogik an einem Ort.
// Benutzerdefinierter Provider mit Zustandsverwaltung
const AuthContext = createContext(null);
function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const login = useCallback(async (email, pass) => {
const u = await loginApi(email, pass);
setUser(u);
}, []);
return (
<AuthContext.Provider value={{ user, login }}>
{children}
</AuthContext.Provider>
);
}
In funktionalen Komponenten ist useContext der einzige Weg, um auf Kontext zuzugreifen. Es ersetzt die Consumer-Komponente der alten Context API, die das Render-Prop-Muster erforderte: <ThemeContext.Consumer>{value => ...}</ThemeContext.Consumer>. useContext macht den Code linearer und lesbarer, insbesondere bei der Arbeit mit mehreren Kontexten in einer Komponente.
Bei der Verwendung mehrerer Kontexte in einer Komponente rufen Sie einfach useContext mehrmals für jeden Kontext auf. Jeder Aufruf gibt den Wert des entsprechenden Providers zurück. Die Reihenfolge der Aufrufe spielt keine Rolle, da jeder Kontext eine unabhängige Einheit ist. React optimiert mehrere Aufrufe über dasselbe Fiber-Referenzsystem.
function Dashboard() {
const { user } = useContext(AuthContext);
const theme = useContext(ThemeContext);
const { locale } = useContext(I18nContext);
return (
<div className={`dashboard-${theme}`}>
<h1>{locale.greeting}, {user.name}</h1>
</div>
);
}
Die Wahl zwischen useContext und Redux hängt vom Umfang und der Komplexität der Zustandsverwaltung ab. useContext + useReducer ist ein leichter Ersatz für Redux für kleine und mittlere Anwendungen. Es erfordert keine Installation einer externen Bibliothek, ist leichter zu erlernen und für die meisten Aufgaben ausreichend. Redux ist gerechtfertigt, wenn eine strenge Architektur mit Middleware, Entwicklertools und unveränderlichen Aktualisierungen erforderlich ist.
Der Hauptvorteil von Redux gegenüber useContext ist die Optimierung des Neurenderns. Standardmäßig werden bei einer Wertänderung in einem Provider alle Kontextkonsumenten neu gerendert. Redux mit useSelector und shallowEqual ermöglicht es Komponenten, nur bestimmte Teile des Zustands zu abonnieren, was die Anzahl der Neurenderungen in großen Anwendungen erheblich reduziert. Kontext kann auch durch Aufteilung in viele kleine Kontexte optimiert werden.
| Kriterium | useContext | Redux |
|---|---|---|
| Komplexität | Keine externen Abhängigkeiten | Erfordert Store- und Middleware-Einrichtung |
| Neurendern | Alle Konsumenten bei jeder Änderung | Nur diejenigen, die einen bestimmten Slice abonnieren |
| DevTools | React DevTools | Redux DevTools mit Zeitreise |
| Middleware | Nicht unterstützt | Redux Thunk, Saga, Observable |
| Wann wählen | Mittlere Apps, 3–5 Kontexte | Große Apps mit komplexer Geschäftslogik |
Laut Redux-Maintainern — Wann Redux verwenden (2024) benötigen 70% der React-Anwendungen kein Redux. Wenn Sie weniger als 50 Komponenten haben und der Zustand keine komplexe Logik mit Caching, Debounce und Seiteneffekten umfasst — ist useContext + useReducer mehr als ausreichend. Redux fügt Boilerplate hinzu und sollte bewusst eingesetzt werden.
Der häufigste Fehler ist das Neuerstellen des Wertobjekts bei jedem Rendern des Providers. Wenn Sie value={{ user, login }} an den Provider übergeben, wird bei jedem Rendern des Providers ein neues Objekt erstellt, was dazu führt, dass alle Konsumenten neu gerendert werden, selbst wenn sich die Daten nicht geändert haben. Die Lösung besteht darin, den Wert mit useMemo zu memoieren oder separate Kontexte für häufig und selten wechselnde Daten zu verwenden.
// ❌ Neues Objekt bei jedem Rendern — alle Konsumenten werden neu gerendert
<AuthContext.Provider value={{ user, login }}>{children}</AuthContext.Provider>
// ✅ Memoierter Wert — Neurendern nur bei Änderung von user oder login
const authValue = useMemo(() => ({ user, login }), [user, login]);
<AuthContext.Provider value={authValue}>{children}</AuthContext.Provider>
Um das Problem des „großen Kontexts“ zu lösen, teilen Sie den globalen Zustand in logische Gruppen auf: AuthContext, ThemeContext, I18nContext. Jeder Kontext ist für seinen eigenen Bereich verantwortlich und aktualisiert sich unabhängig. Dies ist einfacher, als zu versuchen, einen riesigen Kontext durch useMemo zu optimieren, und führt zu einem vorhersehbareren Neurenderungsverhalten.
Häufig gestellte Fragen
Ja, wenn Sie eine Mutator-Funktion im value des Providers übergeben. Das typische Muster besteht darin, den Zustand im Provider zu speichern und sowohl Daten als auch Aktualisierungsfunktionen über useContext zu übergeben. Untergeordnete Komponenten rufen diese Funktionen auf, und die Zustandsänderung im Provider aktualisiert automatisch alle Konsumenten. Dies ist ein grundlegender Redux-Ersatz für kleine Anwendungen.
Für einfache Szenarien ist useContext aufgrund des fehlenden Overheads von Store und Middleware schneller. Bei häufigen Aktualisierungen und vielen Konsumenten hat Redux jedoch die Nase vorn, da seine Selektoren (useSelector) nur bestimmte Teile des Zustands abonnieren, während useContext bei jeder Änderung alle Konsumenten neu rendert. Für Anwendungen mit hoher Aktualisierungshäufigkeit (Animationen, Echtzeit) wählen Sie Redux oder spezialisierte Bibliotheken.
Nein. useContext kann wie alle Hooks nur innerhalb einer funktionalen React-Komponente oder eines benutzerdefinierten Hooks aufgerufen werden. Wenn Sie den Kontextwert in einer normalen Funktion (z. B. in einem Dienstprogramm oder Dienst) benötigen, übergeben Sie ihn als Parameter von der Komponente oder verwenden Sie ein separates Modul mit globalem Zustand außerhalb von React.
Die Typisierung von Kontext in TypeScript erfolgt durch Angabe des Typs in createContext: createContext<AuthContextType | null>(null). Dies stellt sicher, dass useContext(AuthContext) einen Wert des korrekten Typs zurückgibt. Ein praktisches Muster ist die Erstellung eines benutzerdefinierten useAuth-Hooks, der useContext aufruft, auf null prüft und einen klaren Fehler auslöst: „useAuth muss innerhalb von AuthProvider verwendet werden“.
Der häufigste Grund ist, dass sich die Konsumentenkomponente nicht innerhalb des entsprechenden Providers befindet. Überprüfen Sie, ob der Provider den gesamten Teilbaum umschließt, in dem useContext verwendet wird. Der zweite Grund — dem Provider wurde ein anderes Kontextobjekt übergeben: Der Entwickler erstellt einen Kontext mit createContext, verwendet useContext aber mit einer anderen Instanz von createContext.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch