[{"data":1,"prerenderedAt":127},["ShallowReactive",2],{"qa-\u002Freact\u002Fhooks\u002Fusecontext":3},{"page":4,"siblings":99,"blog":124},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"questionsCount":89,"related":90,"seo":91,"seoDescription":92,"stem":93,"subtopic":94,"topic":95,"topicSlug":96,"updated":97,"__hash__":98},"qa\u002Freact\u002Fhooks\u002Fusecontext.md","Usecontext",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"medium","md","React","react",{},true,3,"\u002Freact\u002Fhooks\u002Fusecontext",[23,28,32,36,41,45,49,53,57,61,65,69,73,77,81,85],{"id":24,"difficulty":25,"q":26,"a":27},"what-is-usecontext","easy","What does useContext do?","`useContext` reads the current value of a Context object and subscribes the\ncomponent to updates. When the nearest matching `\u003CProvider>` above it re-renders\nwith a new value, the consumer re-renders with that new value too.\n\n```jsx\nconst theme = useContext(ThemeContext)\n\u002F\u002F reads the value from \u003CThemeContext.Provider value={...}> above\n```\n\nIt replaces the older `\u003CThemeContext.Consumer>` render-prop API with a simple\nfunction call. The context must be created with `React.createContext` and the\ncomponent must be rendered inside the matching Provider.\n\n**Rule of thumb:** `useContext` solves \"prop drilling\" — passing data through many\nlayers of components that don't need it themselves.\n",{"id":29,"difficulty":25,"q":30,"a":31},"create-context","How do you create and provide a context?","Call `createContext` with a default value (used when no Provider is found), then\nwrap the component tree with a `\u003CProvider>` and pass the current value.\n\n```jsx\n\u002F\u002F 1. create\nexport const ThemeContext = createContext('light')\n\n\u002F\u002F 2. provide\nfunction App() {\n  const [theme, setTheme] = useState('dark')\n  return (\n    \u003CThemeContext.Provider value={theme}>\n      \u003CPage \u002F>\n    \u003C\u002FThemeContext.Provider>\n  )\n}\n\n\u002F\u002F 3. consume\nfunction Button() {\n  const theme = useContext(ThemeContext)\n  return \u003Cbutton className={theme}>click\u003C\u002Fbutton>\n}\n```\n\nThe default value passed to `createContext` is only used when a component reads\nthe context without any Provider above it — useful for testing in isolation.\n",{"id":33,"difficulty":14,"q":34,"a":35},"context-default-value","When is the createContext default value used?","The default value is used when a consumer has **no matching Provider** anywhere\nabove it in the tree. It does **not** apply when a Provider passes `undefined` or\n`null` as its `value` — those are valid values that override the default.\n\n```jsx\nconst Ctx = createContext('default')\n\n\u002F\u002F no Provider -> 'default'\nfunction App() {\n  return \u003CChild \u002F>\n}\n\n\u002F\u002F Provider with undefined -> consumer sees undefined, not 'default'\n\u003CCtx.Provider value={undefined}>\n  \u003CChild \u002F> {\u002F* sees undefined *\u002F}\n\u003C\u002FCtx.Provider>\n```\n\nProviding a realistic default value helps when testing components in isolation\nwithout wrapping them in a Provider.\n",{"id":37,"difficulty":38,"q":39,"a":40},"context-rerenders","hard","What triggers a context consumer to re-render?","Every component that calls `useContext(Ctx)` re-renders when the **value** prop on\nthe nearest matching `\u003CCtx.Provider>` changes — React compares by `Object.is`.\n\n```jsx\n\u002F\u002F new object every render -> every consumer re-renders even if data is identical\n\u003CUserContext.Provider value={{ user, setUser }}>\n  ...\n\u003C\u002FUserContext.Provider>\n\n\u002F\u002F stable object -> consumers only re-render when user actually changes\nconst ctxValue = useMemo(() => ({ user, setUser }), [user])\n\u003CUserContext.Provider value={ctxValue}>\n  ...\n\u003C\u002FUserContext.Provider>\n```\n\nThis is the #1 context performance trap. An object\u002Farray literal in the Provider's\nvalue is a new reference every render, causing all consumers to re-render even when\nthe data is unchanged. Memoize the value object to prevent this.\n",{"id":42,"difficulty":14,"q":43,"a":44},"context-vs-props","When should you use context instead of props?","Use context for data that is **globally shared across many components** at\ndifferent nesting levels where passing props becomes verbose: user auth, theme,\nlocale, feature flags. Avoid it for state that only flows two or three levels deep —\nprop drilling that shallow is cleaner and more explicit.\n\n```jsx\n\u002F\u002F fine as props: parent -> child -> grandchild (2 levels)\n\u003CModal title=\"Delete?\" onConfirm={handleDelete} \u002F>\n\n\u002F\u002F better as context: user object needed in nav, sidebar, avatar, settings\nconst { user } = useContext(AuthContext)\n```\n\nContext is not a performance tool — every consumer re-renders on value changes.\nIf you need selective subscriptions, reach for a state management library.\n",{"id":46,"difficulty":14,"q":47,"a":48},"update-context","How do you update context from a consumer?","Include the setter function in the context value alongside the data. Consumers\ncall the setter, which lives in the Provider's parent and causes it to re-render\nwith the new value — which propagates to all consumers.\n\n```jsx\nconst ThemeContext = createContext(null)\n\nfunction ThemeProvider({ children }) {\n  const [theme, setTheme] = useState('dark')\n  return (\n    \u003CThemeContext.Provider value={{ theme, setTheme }}>\n      {children}\n    \u003C\u002FThemeContext.Provider>\n  )\n}\n\nfunction Toggle() {\n  const { theme, setTheme } = useContext(ThemeContext)\n  return \u003Cbutton onClick={() => setTheme(t => t === 'dark' ? 'light' : 'dark')}>{theme}\u003C\u002Fbutton>\n}\n```\n\nThe setter has stable identity (it's a `useState` setter), so including it in the\nvalue doesn't cause extra renders — just make sure to memoize the value object.\n",{"id":50,"difficulty":14,"q":51,"a":52},"multiple-contexts","Can a component read from multiple contexts?","Yes — call `useContext` once per context. There's no limit and each subscription\nis independent.\n\n```jsx\nfunction Dashboard() {\n  const { user } = useContext(AuthContext)\n  const { theme } = useContext(ThemeContext)\n  const { locale } = useContext(LocaleContext)\n  \u002F\u002F ...\n}\n```\n\nEach call registers a separate subscription. The component re-renders whenever\n*any* of the context values changes. If too many contexts cause unwanted renders,\nsplit responsibilities or memoize the component with `React.memo` (though context\nupdates bypass memo).\n",{"id":54,"difficulty":38,"q":55,"a":56},"split-context","How do you avoid unnecessary re-renders caused by a large context?","Split the context by **change frequency**: separate read-rarely data (user profile)\nfrom changes-often data (notifications count). Consumers that only need stable\ndata won't re-render when the volatile part updates.\n\n```jsx\n\u002F\u002F one big context -> all consumers re-render when count changes\n\u003CAppContext.Provider value={{ user, notifCount }}>\n\n\u002F\u002F split by frequency\n\u003CUserContext.Provider value={user}>       {\u002F* changes rarely *\u002F}\n  \u003CNotifContext.Provider value={notifCount}>  {\u002F* changes often *\u002F}\n    \u003CApp \u002F>\n  \u003C\u002FNotifContext.Provider>\n\u003C\u002FUserContext.Provider>\n```\n\nComponents reading only `UserContext` are unaffected by notification updates.\nThis is the recommended pattern over a single monolithic context.\n",{"id":58,"difficulty":38,"q":59,"a":60},"context-memo-bypass","Does React.memo protect a component from context re-renders?","No. `React.memo` skips re-renders when **props** don't change, but it has no\neffect on context updates — a memoized component still re-renders when a context\nvalue it reads changes.\n\n```jsx\nconst MemoButton = React.memo(function Button() {\n  const theme = useContext(ThemeContext) \u002F\u002F still re-renders on ThemeContext change\n  return \u003Cbutton className={theme}>click\u003C\u002Fbutton>\n})\n```\n\nTo avoid unnecessary renders, memoize the context **value** at the Provider level\n(so it doesn't change unnecessarily) rather than trying to memo the consumers.\n",{"id":62,"difficulty":14,"q":63,"a":64},"context-vs-redux","When should you use context vs. a state management library?","**Context** suits simple, low-frequency global data: auth session, theme, locale.\nIt re-renders all consumers on any change and has no built-in selectors or\nmiddleware.\n\n**State management libraries** (Redux Toolkit, Zustand, Jotai) suit complex,\nfrequently-changing shared state where you need selective subscriptions (only\nre-render components that care about specific slices), devtools, or middleware\nlike logging and async thunks.\n\n```jsx\n\u002F\u002F context: good for this\nconst { user } = useContext(AuthContext)   \u002F\u002F stable, infrequent\n\n\u002F\u002F library: better for this\nconst cartCount = useSelector(state => state.cart.items.length) \u002F\u002F selective\n```\n\nThe context API is built in and zero-cost; a library adds a dependency but pays\nfor itself with high-churn data.\n",{"id":66,"difficulty":25,"q":67,"a":68},"context-vs-consumer","How does useContext compare to the Context.Consumer component?","Both read the same context value, but `useContext` is simpler — you call it and\nget the value directly instead of rendering a component with a render-prop callback.\n\n```jsx\n\u002F\u002F old: Consumer render prop\n\u003CThemeContext.Consumer>\n  {theme => \u003Cbutton className={theme}>click\u003C\u002Fbutton>}\n\u003C\u002FThemeContext.Consumer>\n\n\u002F\u002F new: useContext\nconst theme = useContext(ThemeContext)\n```\n\n`useContext` also avoids the nesting (\"callback hell\") when consuming multiple\ncontexts. Functionally they are equivalent; `useContext` is the idiomatic modern\napproach.\n",{"id":70,"difficulty":14,"q":71,"a":72},"context-provider-pattern","What is the context + provider custom hook pattern?","Encapsulate the context, Provider, and a custom hook in one file so consumers\nnever import the raw context object — they only call the hook. The hook also\nenforces that the component is inside the Provider.\n\n```jsx\nconst AuthContext = createContext(null)\n\nexport function AuthProvider({ children }) {\n  const [user, setUser] = useState(null)\n  return \u003CAuthContext.Provider value={{ user, setUser }}>{children}\u003C\u002FAuthContext.Provider>\n}\n\nexport function useAuth() {\n  const ctx = useContext(AuthContext)\n  if (!ctx) throw new Error('useAuth must be used within AuthProvider')\n  return ctx\n}\n```\n\nConsumers call `useAuth()` directly, which gives a clear error if they're\naccidentally rendered outside the Provider rather than silently getting `null`.\n",{"id":74,"difficulty":14,"q":75,"a":76},"context-testing","How do you test components that consume context?","Wrap the component under test in the Provider with a test value, or create a\nhelper wrapper function for your testing library.\n\n```jsx\nfunction renderWithAuth(ui, { user = testUser } = {}) {\n  return render(\n    \u003CAuthProvider initialUser={user}>{ui}\u003C\u002FAuthProvider>\n  )\n}\n\ntest('shows username', () => {\n  renderWithAuth(\u003CProfile \u002F>)\n  expect(screen.getByText('Ada')).toBeInTheDocument()\n})\n```\n\nThis is why the \"Provider + custom hook\" pattern is useful: you can also supply\na mock Provider in tests that returns controlled values without hitting real auth.\n",{"id":78,"difficulty":38,"q":79,"a":80},"context-stale","Can context cause stale data bugs similar to useEffect closures?","Yes, if you capture a context value in a callback or effect and the context value\nlater changes, the closure holds the old value. The fix is the same: include the\ncontext value in the dependency array of effects and callbacks.\n\n```jsx\nconst { user } = useContext(AuthContext)\nuseEffect(() => {\n  log(user.id) \u002F\u002F safe: re-runs when user changes\n}, [user])\n\nconst handleClick = useCallback(() => {\n  post(user.id) \u002F\u002F safe: recreated when user changes\n}, [user])\n```\n\n`useContext` itself is always fresh (it reads the current value), but captured\nclosures aren't — always list context-derived values in your dependency arrays.\n",{"id":82,"difficulty":38,"q":83,"a":84},"context-propagation-skip","Can you stop context from propagating to part of the tree?","Yes — render another Provider with a **different value** lower in the tree. All\nconsumers below it receive the new value instead of the one from above.\n\n```jsx\n\u003CThemeContext.Provider value=\"dark\">\n  \u003CHeader \u002F>  {\u002F* sees 'dark' *\u002F}\n  \u003CThemeContext.Provider value=\"light\">\n    \u003CSidebar \u002F>  {\u002F* sees 'light' *\u002F}\n  \u003C\u002FThemeContext.Provider>\n\u003C\u002FThemeContext.Provider>\n```\n\nThis is how libraries like `react-query` allow nested query clients. You cannot\n\"block\" a context — only override it with a new Provider further down.\n",{"id":86,"difficulty":14,"q":87,"a":88},"context-lazy-init","How do you lazily initialize context state?","Pass a function to `useState` inside the Provider's component, just as you would\nfor any expensive initial computation.\n\n```jsx\nfunction AuthProvider({ children }) {\n  const [user, setUser] = useState(() => JSON.parse(localStorage.getItem('user')))\n  return (\n    \u003CAuthContext.Provider value={{ user, setUser }}>\n      {children}\n    \u003C\u002FAuthContext.Provider>\n  )\n}\n```\n\nThe lazy initializer runs once, so the `localStorage` parse only happens on\nmount. This is especially useful for context that hydrates from storage or a\ncookie without re-parsing on every render.\n",16,null,{"description":11},"React useContext interview questions — creating and consuming context, avoiding unnecessary re-renders, splitting contexts, and context vs state management.","react\u002Fhooks\u002Fusecontext","useContext","Hooks","hooks","2026-06-23","uEm9a7m1liNgtTD-nuFSTPFcKLtu4BYjHpDNjkPPqmw",[100,104,107,108,112,116,120],{"subtopic":101,"path":102,"order":103},"useState","\u002Freact\u002Fhooks\u002Fusestate",1,{"subtopic":105,"path":106,"order":12},"useEffect","\u002Freact\u002Fhooks\u002Fuseeffect",{"subtopic":94,"path":21,"order":20},{"subtopic":109,"path":110,"order":111},"useReducer","\u002Freact\u002Fhooks\u002Fusereducer",4,{"subtopic":113,"path":114,"order":115},"useCallback & useMemo","\u002Freact\u002Fhooks\u002Fusecallback-usememo",5,{"subtopic":117,"path":118,"order":119},"useRef","\u002Freact\u002Fhooks\u002Fuseref",6,{"subtopic":121,"path":122,"order":123},"Custom Hooks","\u002Freact\u002Fhooks\u002Fcustom-hooks",7,{"path":125,"title":126},"\u002Fblog\u002Freact-usecontext-hook-guide","React useContext Hook — Complete Guide for Interviews",1782244100836]