Join the discussion
Comments
Loading comments...
Cookie preferences
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Join the discussion
Loading comments...
We use essential cookies for sign-in and preferences. With your permission, we also use basic analytics to improve lessons.
Wie React Werte ohne Prop-Drilling durch den Komponentenbaum übergibt.
Die Context API ermöglicht die gemeinsame Nutzung von Daten im Komponentenbaum, ohne Props auf jeder Ebene weiterzureichen (Prop-Drilling). Eine Provider-Komponente umhüllt einen Teilbaum und stellt einen Wert bereit. Jede Nachfolger-Komponente kann diesen Wert mit useContext lesen — und wird automatisch neu gerendert, wenn sich der Wert ändert.
React.createContext(Standardwert) erstellt ein Context-Objekt mit einem Provider und Consumer. Der Standardwert wird verwendet, wenn eine Komponente Kontext ohne passenden Provider über sich im Baum abruft.
Die Provider-Komponente akzeptiert eine value-Prop. Alle Komponenten im Teilbaum können auf diesen Wert zugreifen. Sie können mehrere Provider desselben Kontexts verschachteln — der nächste Vorfahren-Provider gewinnt.
useContext(MeinKontext) gibt den aktuellen Kontextwert vom nächsten Provider über der aufrufenden Komponente zurück. Es abonniert die Komponente für Kontextänderungen.
Wenn sich die value-Prop des Providers ändert (nach Referenz), rendert React ALLE Komponenten neu, die useContext(MeinKontext) im Teilbaum aufrufen — unabhängig davon, ob sich der tatsächlich genutzte Wert geändert hat.
Dies ist die wichtigste Effizienz: Zwischenkomponenten, die useContext nicht aufrufen, werden nicht neu gerendert. Kontext überspringt sie. Nur tatsächliche Consumer werden neu gerendert.
Erstellt ein Context-Objekt. Nimmt einen Standardwert an, der verwendet wird, wenn kein Provider über dem Consumer im Baum vorhanden ist.
Sendet einen Wert an alle Nachfolger-Consumer. Verschachtelte Provider überschreiben äußere. Der Wert sollte memoisiert sein, um unnötige Re-Renderings zu verhindern.
Hook, der eine Komponente für einen Kontext abonniert. Rendert neu, wenn sich der Kontextwert ändert.
Kontext springt direkt zu Consumern — Zwischenkomponenten rendern nicht neu, es sei denn, sie rufen auch useContext auf.
React vergleicht Kontextwerte mit Object.is(). Das Übergeben eines neuen Objektliterals '{''}' bei jedem Rendering löst das Neu-Rendering aller Consumer aus, selbst wenn der Inhalt identisch ist.
1const ThemeContext = React.createContext('light'); // default23// Provider — wrap at the top level4function App() {5 const [theme, setTheme] = useState('dark');67 // ⚠️ Memoize the value to avoid re-rendering all consumers8 // on every App render, even when theme hasn't changed9 const value = useMemo(() => ({ theme, setTheme }), [theme]);1011 return (12 <ThemeContext.Provider value={value}>13 <Layout />14 </ThemeContext.Provider>15 );16}1718// Consumer — anywhere in the subtree19function Button() {20 const { theme } = useContext(ThemeContext);21 return <button className={theme}>Click</button>;22}
Kontext löst Prop-Drilling — das Weiterreichen von Props durch viele Komponentenebenen, nur um Daten an ein tief verschachteltes Kind zu liefern. Kontext eignet sich am besten für wirklich globale oder weit geteilte Daten (Authentifizierung, Theme, Locale). Für häufig ändernde Werte bevorzugen Sie Zustand oder Redux, um zu vermeiden, dass jeder Consumer bei jeder Änderung neu gerendert wird.
Your app has a global theme context providing colors, fonts, and dark/light mode. After adding it, every keystroke in a form input re-renders the entire app because the ThemeProvider is at the root.
The context value is `{ theme, toggleTheme }`. If the ThemeProvider's parent re-renders for ANY reason (new route, state change), a new object is created → all consumers re-render. With 50+ themed components, every parent re-render triggers 50+ unnecessary re-renders.
Split into two contexts: `ThemeValueContext` (read-only, changes only on toggle) and `ThemeDispatchContext` (stable setter function). Components that only READ the theme subscribe to ThemeValueContext. Components that only TOGGLE subscribe to ThemeDispatchContext. Memoize both values with useMemo.
Takeaway: Split contexts by update frequency: separate rarely-changing data (theme colors) from frequently-changing data (user input). This prevents the 'context-triggers-everything' problem and is the pattern used by Redux, Zustand, and Jotai internally.
A settings page passes `locale`, `currency`, and `dateFormat` through 6 levels of nesting: Settings → Layout → Panel → Section → Field → Label. Adding a new preference requires editing 6 components.
Prop drilling creates tight coupling — every intermediate component must know about and forward props it doesn't use. Adding, renaming, or removing a preference requires changing every component in the chain. The intermediate components also re-render when props change even though they don't USE the data.
Create a `PreferencesContext` and consume it directly in Label with `useContext(PreferencesContext)`. Intermediate components (Layout, Panel, Section, Field) don't receive or forward preference props. The preferences data 'teleports' from Provider to consumer, skipping all intermediate components.
Takeaway: Context eliminates prop drilling for cross-cutting concerns (theme, auth, locale, feature flags). Use it when data needs to be available deep in the tree and passing it through 3+ levels of components that don't use it. For frequently-updating state, consider a state manager instead.