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.
React कैसे prop drilling के बिना component tree में values पहुंचाता है।
Context API आपको component tree में हर स्तर पर props pass किए बिना data share करने देता है (prop drilling)। एक Provider component एक subtree को wrap करता है और एक value provide करता है। कोई भी descendant component useContext से उस value को access कर सकता है — और value बदलने पर automatically re-render होगा।
React.createContext(defaultValue) एक Context object बनाता है जिसमें Provider और Consumer होते हैं। defaultValue तब उपयोग होती है जब कोई component tree में matching Provider के बिना context consume करे।
Provider component एक value prop accept करता है। Subtree के सभी components इस value को access कर सकते हैं। आप एक ही context के multiple Providers nest कर सकते हैं — सबसे नज़दीकी ancestor Provider जीतता है।
useContext(MyContext) calling component के ऊपर सबसे नज़दीकी Provider से current context value return करता है। यह component को context changes के लिए subscribe करता है।
जब Provider का value prop (reference से) बदलता है, React subtree में useContext(MyContext) call करने वाले सभी components को re-render करता है — चाहे उनकी consume की गई value actually बदली हो या नहीं।
यही key efficiency है: intermediate components जो useContext call नहीं करते, re-render नहीं होते। Context उन्हें skip करता है। केवल actual consumers re-render होते हैं।
एक context object बनाता है। एक default value लेता है जो तब उपयोग होती है जब tree में consumer के ऊपर कोई Provider न हो।
सभी descendant consumers को एक value broadcast करता है। Nested Providers बाहरी ones को override करते हैं। Unnecessary re-renders रोकने के लिए Value को memoize करना चाहिए।
Hook जो एक component को context subscribe करता है। Context value बदलने पर re-render होता है।
Context सीधे consumers तक पहुंचता है — intermediate components तब तक re-render नहीं होते जब तक वे भी useContext call न करें।
React context values को Object.is() से compare करता है। हर render पर नया object literal '{''}' pass करने से सभी consumers re-render होते हैं, भले ही contents same हों।
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}
Context prop drilling को solve करता है — deeply nested child तक data पहुंचाने के लिए कई layers के components से props pass करना। लेकिन context वास्तव में global या widely-shared data (auth, theme, locale) के लिए सबसे अच्छा है। बार-बार बदलने वाली values के लिए, हर change पर हर consumer को re-render होने से बचाने के लिए Zustand या Redux prefer करें।
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.