[{"data":1,"prerenderedAt":112},["ShallowReactive",2],{"qa-\u002Freact\u002Fstate-and-data-flow\u002Fcontext-api":3},{"page":4,"siblings":95,"blog":109},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":20,"order":12,"path":21,"questions":22,"questionsCount":85,"related":86,"seo":87,"seoDescription":88,"stem":89,"subtopic":90,"topic":91,"topicSlug":92,"updated":93,"__hash__":94},"qa\u002Freact\u002Fstate-and-data-flow\u002Fcontext-api.md","Context Api",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"medium","md","React","react",{"subtopicSlug":19},"context-api",true,"\u002Freact\u002Fstate-and-data-flow\u002Fcontext-api",[23,28,32,36,40,44,48,52,56,60,65,69,73,77,81],{"id":24,"difficulty":25,"q":26,"a":27},"context-what","easy","What problem does the React Context API solve?","Context provides a way to pass data through the component tree **without\nthreading props through every intermediate level** — solving what is\nknown as **prop drilling**.\n\n```jsx\n\u002F\u002F Without Context — every layer must pass `theme` down\n\u003CApp theme=\"dark\">\n  \u003CLayout theme=\"dark\">\n    \u003CSidebar theme=\"dark\">\n      \u003CButton theme=\"dark\" \u002F>\n    \u003C\u002FSidebar>\n  \u003C\u002FLayout>\n\u003C\u002FApp>\n\n\u002F\u002F With Context — Button reads theme directly\nconst ThemeContext = createContext('light')\n\nfunction App() {\n  return (\n    \u003CThemeContext.Provider value=\"dark\">\n      \u003CLayout \u002F>         {\u002F* no theme prop needed *\u002F}\n    \u003C\u002FThemeContext.Provider>\n  )\n}\n\nfunction Button() {\n  const theme = useContext(ThemeContext)   \u002F\u002F reads directly\n  return \u003Cbutton className={theme}>Click\u003C\u002Fbutton>\n}\n```\n\n**Rule of thumb:** Use Context for truly global or widely shared data\n(theme, locale, auth user). Don't reach for it to avoid one or two\nlevels of prop passing.\n",{"id":29,"difficulty":25,"q":30,"a":31},"context-create","What does createContext do and what does its argument represent?","`createContext(defaultValue)` creates a Context object. The\n**default value** is used only when a component reads the context\n*without* a matching `Provider` above it in the tree — it is not the\ninitial value of the Provider.\n\n```jsx\n\u002F\u002F Default value is 'light' — used only outside any Provider\nconst ThemeContext = createContext('light')\n\nfunction App() {\n  return (\n    \u003CThemeContext.Provider value=\"dark\">\n      \u003CChild \u002F>   {\u002F* reads 'dark' *\u002F}\n    \u003C\u002FThemeContext.Provider>\n  )\n}\n\nfunction Orphan() {\n  \u002F\u002F No Provider above → reads the default 'light'\n  const theme = useContext(ThemeContext)\n  return \u003Cdiv>{theme}\u003C\u002Fdiv>\n}\n```\n\n**Rule of thumb:** Set the default value to something that makes the\ncomponent usable in isolation (e.g. in tests or Storybook) without\nwrapping it in a Provider.\n",{"id":33,"difficulty":25,"q":34,"a":35},"context-use-context","How do you consume a context value inside a function component?","Call `useContext(MyContext)` at the top level of the component. It\nreturns the current context value provided by the nearest matching\n`Provider` up the tree.\n\n```jsx\nimport { createContext, useContext } from 'react'\n\nconst UserContext = createContext(null)\n\nfunction Greeting() {\n  const user = useContext(UserContext)\n  if (!user) return \u003Cp>Please log in\u003C\u002Fp>\n  return \u003Cp>Hello, {user.name}\u003C\u002Fp>\n}\n\nfunction App() {\n  const [user] = useState({ name: 'Alice' })\n  return (\n    \u003CUserContext.Provider value={user}>\n      \u003CGreeting \u002F>\n    \u003C\u002FUserContext.Provider>\n  )\n}\n```\n\n**Rule of thumb:** `useContext` is the modern replacement for the legacy\n`Context.Consumer` render-prop API. Use it exclusively in function\ncomponents.\n",{"id":37,"difficulty":14,"q":38,"a":39},"context-re-renders","When does a context change cause re-renders, and which components are affected?","Every component that calls `useContext(MyContext)` **re-renders** when\nthe Provider's `value` prop changes (by reference). Intermediate\ncomponents that don't consume the context are **not** re-rendered.\n\n```jsx\nconst CountCtx = createContext(0)\n\nfunction Parent() {\n  const [count, setCount] = useState(0)\n  return (\n    \u002F\u002F Object literal creates a new reference every render — all consumers re-render\n    \u003CCountCtx.Provider value={{ count, setCount }}>\n      \u003CMiddle \u002F>\n    \u003C\u002FCountCtx.Provider>\n  )\n}\n\nfunction Middle() {\n  \u002F\u002F does NOT use CountCtx → NOT re-rendered when count changes\n  return \u003CConsumer \u002F>\n}\n\nfunction Consumer() {\n  const { count } = useContext(CountCtx)   \u002F\u002F re-renders on every count change\n  return \u003Cspan>{count}\u003C\u002Fspan>\n}\n```\n\n**Rule of thumb:** Memoize the context value (`useMemo`) when the\nProvider's parent re-renders frequently to avoid creating a new\nreference each time.\n",{"id":41,"difficulty":14,"q":42,"a":43},"context-value-memo","Why should you memoize the value passed to a Context Provider?","Every time the Provider's parent re-renders, a new object or array\nliteral creates a **new reference**. React's shallow equality check\nsees a new reference → all consumers re-render even if the data\nhasn't changed.\n\n```jsx\n\u002F\u002F ❌ New object every render → all consumers re-render needlessly\n\u003CAuthContext.Provider value={{ user, logout }}>\n\n\u002F\u002F ✅ Stable reference — only changes when user or logout changes\nconst authValue = useMemo(() => ({ user, logout }), [user, logout])\n\u003CAuthContext.Provider value={authValue}>\n```\n\nIf the value is a primitive (string, number) memoisation is\nunnecessary because primitives are compared by value.\n\n**Rule of thumb:** Whenever you pass an object or array as a context\nvalue, wrap it in `useMemo`.\n",{"id":45,"difficulty":14,"q":46,"a":47},"context-multiple","Can a component use multiple contexts, and how do you compose multiple Providers?","Yes. Call `useContext` once per context. Compose Providers by nesting\nthem at the top of the tree — order only matters if a Provider reads\nfrom a sibling context.\n\n```jsx\nfunction App() {\n  return (\n    \u003CThemeContext.Provider value=\"dark\">\n      \u003CAuthContext.Provider value={currentUser}>\n        \u003CLocaleContext.Provider value=\"en\">\n          \u003CRouter \u002F>\n        \u003C\u002FLocaleContext.Provider>\n      \u003C\u002FAuthContext.Provider>\n    \u003C\u002FThemeContext.Provider>\n  )\n}\n\nfunction Header() {\n  const theme  = useContext(ThemeContext)\n  const user   = useContext(AuthContext)\n  const locale = useContext(LocaleContext)\n  \u002F\u002F ...\n}\n```\n\nIf nesting becomes unwieldy, extract a single `AppProviders` wrapper\ncomponent that composes them all.\n\n**Rule of thumb:** Create one context per concern; don't cram unrelated\nvalues into a single context object.\n",{"id":49,"difficulty":14,"q":50,"a":51},"context-vs-props","When should you use Context instead of props?","Use Context when data is needed by **many components at different nesting\nlevels** and passing it via props would require threading it through\nmany intermediate layers that don't need it themselves.\n\n| Signal | Prefer |\n|---|---|\n| 1–2 levels of passing | Props |\n| Truly global (theme, locale, auth) | Context |\n| Frequently changes, many subscribers | External store |\n\n```jsx\n\u002F\u002F Props are fine — shallow tree, one consumer\n\u003CPage>\u003CCard title={title} \u002F>\u003C\u002FPage>\n\n\u002F\u002F Context fits — auth needed everywhere, changes rarely\n\u003CAuthContext.Provider value={user}>\n  \u003CNavbar \u002F>\u003CRoutes \u002F>\u003CFooter \u002F>\n\u003C\u002FAuthContext.Provider>\n```\n\n**Rule of thumb:** If you're passing the same prop through 3+ levels\nthat don't use it, that's the signal to consider Context.\n",{"id":53,"difficulty":14,"q":54,"a":55},"context-vs-redux","What are the main differences between Context and a library like Redux?","| Aspect | Context | Redux \u002F Zustand |\n|---|---|---|\n| Built-in | Yes | External dependency |\n| Re-render granularity | All consumers of the context | Selector-level (only subscribe to what you need) |\n| DevTools | None | Time-travel, action log |\n| Async logic | Manual | Built-in middleware (thunk, saga) |\n| Boilerplate | Low | Medium (RTK reduces it) |\n\nContext is best for **infrequently changing** global values (theme,\nlocale, authenticated user). For **frequently updating** shared state\nwith many subscribers, a store library avoids cascade re-renders.\n\n**Rule of thumb:** Don't reach for Redux just because you have global\nstate. Context + `useReducer` covers a lot of ground; add a store\nwhen you need fine-grained subscriptions or middleware.\n",{"id":57,"difficulty":14,"q":58,"a":59},"context-custom-hook","Why is it a good practice to wrap useContext in a custom hook?","A custom hook hides the context import, adds a helpful error message\nwhen used outside the Provider, and creates a stable API so consumers\ndon't need to know which context backs it.\n\n```jsx\n\u002F\u002F context\u002FThemeContext.jsx\nconst ThemeContext = createContext(null)\n\nexport function 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\nexport function useTheme() {\n  const ctx = useContext(ThemeContext)\n  if (!ctx) throw new Error('useTheme must be used inside ThemeProvider')\n  return ctx\n}\n\n\u002F\u002F Consumer — no context import needed\nconst { theme, setTheme } = useTheme()\n```\n\n**Rule of thumb:** Always export a `useFoo()` hook instead of\nexporting the raw Context object.\n",{"id":61,"difficulty":62,"q":63,"a":64},"context-split-concerns","hard","How can you split a context to avoid unnecessary re-renders when only part of the value changes?","Provide **separate contexts** for state and dispatch (or read vs.\nwrite). Components that only dispatch won't re-render when state\nchanges, and vice versa.\n\n```jsx\nconst CountStateCtx   = createContext(null)\nconst CountDispatchCtx = createContext(null)\n\nfunction CountProvider({ children }) {\n  const [count, dispatch] = useReducer(reducer, 0)\n  return (\n    \u003CCountDispatchCtx.Provider value={dispatch}>\n      \u003CCountStateCtx.Provider value={count}>\n        {children}\n      \u003C\u002FCountStateCtx.Provider>\n    \u003C\u002FCountDispatchCtx.Provider>\n  )\n}\n\n\u002F\u002F Only re-renders when count changes\nfunction Counter()   { return \u003Cspan>{useContext(CountStateCtx)}\u003C\u002Fspan> }\n\n\u002F\u002F Never re-renders due to count changes (dispatch is stable)\nfunction IncrBtn()   { return \u003Cbutton onClick={() => useContext(CountDispatchCtx)({ type: 'inc' })}>+\u003C\u002Fbutton> }\n```\n\n**Rule of thumb:** If your context value has both frequently-changing\nstate and stable callbacks, put them in separate contexts.\n",{"id":66,"difficulty":14,"q":67,"a":68},"context-with-reducer","How do you combine useReducer with Context to implement a lightweight global store?","Keep `useReducer` in a Provider component. Pass state via one context\nand the stable `dispatch` via another (or together if updates are\ninfrequent).\n\n```jsx\nconst StoreCtx = createContext(null)\n\nfunction reducer(state, action) {\n  switch (action.type) {\n    case 'SET_USER': return { ...state, user: action.payload }\n    case 'LOGOUT':   return { ...state, user: null }\n    default:         return state\n  }\n}\n\nexport function StoreProvider({ children }) {\n  const [state, dispatch] = useReducer(reducer, { user: null })\n  const value = useMemo(() => ({ state, dispatch }), [state])\n  return \u003CStoreCtx.Provider value={value}>{children}\u003C\u002FStoreCtx.Provider>\n}\n\nexport const useStore = () => useContext(StoreCtx)\n```\n\nThis pattern gives you Redux-like action dispatch without adding a\ndependency — ideal for small to medium apps.\n\n**Rule of thumb:** `useReducer` + Context is the sweet spot before you\nneed Redux's devtools or middleware.\n",{"id":70,"difficulty":62,"q":71,"a":72},"context-lazy-init","How do you avoid expensive context value recomputation on every render?","Use `useMemo` for objects\u002Farrays passed as the context value, and\n`useCallback` for functions, so React sees a stable reference and\nskips re-rendering consumers.\n\n```jsx\nfunction AuthProvider({ children }) {\n  const [user, setUser] = useState(null)\n\n  const logout = useCallback(() => {\n    setUser(null)\n    api.logout()\n  }, [])                         \u002F\u002F stable function reference\n\n  const value = useMemo(\n    () => ({ user, logout }),\n    [user, logout]               \u002F\u002F recompute only when user changes\n  )\n\n  return \u003CAuthContext.Provider value={value}>{children}\u003C\u002FAuthContext.Provider>\n}\n```\n\n**Rule of thumb:** Any context value that is an object or contains\nfunctions should be memoised at the Provider level.\n",{"id":74,"difficulty":14,"q":75,"a":76},"context-default-null","Should the default value of createContext be null or a sensible fallback, and why?","Using `null` (or `undefined`) as the default forces consumers to handle\nthe \"no Provider\" case explicitly and makes it easy to detect misuse.\nA non-null default value makes the component work outside a Provider,\nwhich is useful for testing and Storybook.\n\n```jsx\n\u002F\u002F null default — consumers must check or use a custom hook with an error\nconst AuthContext = createContext(null)\n\n\u002F\u002F Non-null default — component works in isolation; good for theming\nconst ThemeContext = createContext({ mode: 'light', toggle: () => {} })\n```\n\nChoose based on intent:\n- If the component **cannot** work without a Provider → default `null`,\n  throw in the custom hook.\n- If the component **can** work standalone → provide a real fallback.\n\n**Rule of thumb:** Auth\u002Fsession contexts default to `null`; config\u002Ftheme\ncontexts default to a sensible fallback object.\n",{"id":78,"difficulty":25,"q":79,"a":80},"context-provider-location","Where in the component tree should a Context Provider be placed?","As **low as possible** while still wrapping all consumers. Placing it\ntoo high (e.g. at app root) means unrelated subtrees re-render when\nthe context value changes.\n\n```jsx\n\u002F\u002F ❌ Too high — the entire app re-renders when modal state changes\nfunction App() {\n  const [isOpen, setIsOpen] = useState(false)\n  return (\n    \u003CModalContext.Provider value={{ isOpen, setIsOpen }}>\n      \u003CHeader \u002F>\u003CMain \u002F>\u003CFooter \u002F>\n    \u003C\u002FModalContext.Provider>\n  )\n}\n\n\u002F\u002F ✅ Scoped to the subtree that needs it\nfunction CheckoutPage() {\n  const [isOpen, setIsOpen] = useState(false)\n  return (\n    \u003CModalContext.Provider value={{ isOpen, setIsOpen }}>\n      \u003CCheckoutForm \u002F>\u003CConfirmModal \u002F>\n    \u003C\u002FModalContext.Provider>\n  )\n}\n```\n\n**Rule of thumb:** The Provider should be the lowest ancestor that\ncontains all the components that consume the context.\n",{"id":82,"difficulty":14,"q":83,"a":84},"context-testing","How do you test a component that depends on a Context value?","Wrap the component under test in the Provider and supply a controlled\ntest value. With React Testing Library:\n\n```jsx\nimport { render, screen } from '@testing-library\u002Freact'\nimport { ThemeContext } from '.\u002FThemeContext'\nimport ThemedButton from '.\u002FThemedButton'\n\nfunction renderWithTheme(ui, theme = 'light') {\n  return render(\n    \u003CThemeContext.Provider value={theme}>\n      {ui}\n    \u003C\u002FThemeContext.Provider>\n  )\n}\n\ntest('applies dark class in dark mode', () => {\n  renderWithTheme(\u003CThemedButton \u002F>, 'dark')\n  expect(screen.getByRole('button')).toHaveClass('dark')\n})\n```\n\nAlternatively, if you use the custom-hook pattern, wrap in the real\nProvider component from your codebase.\n\n**Rule of thumb:** Never mock context directly — always wrap with the\nreal Provider so tests exercise the full integration.\n",15,null,{"description":11},"React Context API interview questions — createContext, useContext, Provider, re-render behaviour, multiple contexts, and when to use Context vs. Redux.","react\u002Fstate-and-data-flow\u002Fcontext-api","Context API","State and Data Flow","state-and-data-flow","2026-06-24","p6lfuFzLj8fO3W-l3h9Fm_ohOc8gnQ0e80jy7K7bRmU",[96,100,101,105],{"subtopic":97,"path":98,"order":99},"Lifting State Up","\u002Freact\u002Fstate-and-data-flow\u002Flifting-state",1,{"subtopic":90,"path":21,"order":12},{"subtopic":102,"path":103,"order":104},"Controlled vs Uncontrolled Components","\u002Freact\u002Fstate-and-data-flow\u002Fcontrolled-vs-uncontrolled",3,{"subtopic":106,"path":107,"order":108},"Prop Drilling and Composition","\u002Freact\u002Fstate-and-data-flow\u002Fprop-drilling-composition",4,{"path":110,"title":111},"\u002Fblog\u002Freact-context-api-guide","React Context API — A Complete Guide",1782244100910]