ReactContext Apiintermediate
Updated:

React Context API Interview Questions and Answers

6 min read

The Context API questions React interviews ask — createContext and useContext, the Provider, why consumers re-render, memoizing values and Context vs Redux.

TL;DR – Quick Answer

React Context interviews test what Context is for — passing a value deep into the tree without prop drilling — and, more importantly, its performance behaviour: every consumer re-renders when the Provider value changes, so unstable values and one oversized context are the usual bugs. Interviewers probe createContext, useContext, the Provider, memoizing the value, splitting contexts, and when Context is the wrong tool versus a store.

On This Page

The Context API is a small feature with a large interview footprint, because it is easy to use and easy to misuse. Interviewers want to know that you can wire it up, but mostly they want to hear the performance story — why every consumer re-renders when the value changes, and how you keep that from turning Context into a bottleneck. The questions below cover the mechanics and, more importantly, the judgement.

How to answer Context questions

Say what Context is and what it is not. It is a transport that passes a value deep into the tree without prop drilling; it is not a state manager, and it has no way to subscribe to part of a value. Every strong answer here comes back to one fact: consumers re-render when the Provider value changes by reference. Lead with that and the follow-ups about memoization and splitting contexts answer themselves.

Q1. What problem does Context solve, and when do you reach for it?

Context passes data to deeply nested components without prop drilling — threading a prop through intermediate components that do not use it. Reach for it with genuinely global, low-frequency data: theme, authenticated user, locale, feature flags. For data only a few nearby components need, lifting state or composition is simpler.

The trap is treating Context as the first answer to any shared state. It shines for data that is truly cross-cutting and changes rarely; it hurts for data that changes often, because of the re-render behaviour in Q3.

Interview note: Follow-up: "Context vs prop drilling for two levels?" Two levels of drilling is usually clearer than a context; add Context when the depth or number of consumers makes drilling genuinely painful.

Q2. How do you create and consume a Context?

Create it with createContext(defaultValue), provide a value with <MyContext.Provider value={...}> wrapping the subtree, and read it in any descendant with the useContext(MyContext) hook. The default value is only used when a consumer has no Provider above it.

const ThemeContext = createContext("light");

function App() {
  const [theme, setTheme] = useState("dark");
  return (
    <ThemeContext.Provider value={theme}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}
function Toolbar() {
  const theme = useContext(ThemeContext); // no prop drilling
  return <div className={theme}>...</div>;
}

Interview note: Follow-up: "when is the default value used?" Only when a component calls useContext with no matching Provider above it — useful for standalone tests, and a signal you forgot a Provider if you see it in the app.

Q3. Why do all consumers re-render when the context value changes?

A component calling useContext subscribes to the entire context value. When the Provider's value changes by reference, React re-renders every consumer, regardless of whether they use the part that changed. There is no built-in partial subscription — this is Context's defining performance characteristic.

The most common accidental version: passing an inline object as the value. value={{ user, setUser }} creates a new object every render, so every consumer re-renders on every Provider render, even when user never changed.

Interview note: Trap: "how do you subscribe to just one field of a context?" You cannot with plain Context — you split contexts or use a store with selectors. Recognising this limit is the point of the question.

Q4. How do you fix unnecessary Context re-renders?

Three tactics: memoize the Provider value with useMemo so its reference is stable, split one large context into several focused ones, and separate rarely-changing data from frequently-changing data so consumers subscribe only to what they need.

function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  const value = useMemo(() => ({ user, setUser }), [user]); // stable reference
  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

Interview note: Follow-up: "you memoized the value but consumers still re-render on unrelated changes — why?" The context still holds multiple fields; a change to any of them changes the value. Split the context so each concern updates independently.

Q5. Why split one context into several?

Because a single context holding user, theme and a live-updating value re-renders every consumer whenever any part changes. Splitting into AuthContext, ThemeContext and so on means a theme change no longer re-renders auth consumers. Group by update frequency and by which components actually need each slice.

This is the standard senior answer to "our app re-renders too much and it uses Context." The fix is architectural — smaller, purpose-built contexts — not more memoization.

Interview note: Trap: "isn't one context simpler?" Simpler to write, worse to run at scale; the re-render cost grows with consumers. Split before it becomes a performance problem.

Q6. Context vs Redux (or another store) — how do you choose?

Context is a transport for a value with no selectors, middleware or devtools, re-rendering all consumers on change — ideal for small, rarely-changing global data. A store like Redux or Zustand offers selective subscription (components read only their slice), middleware and tooling — ideal for large, frequently-updated shared state. They are different tools; a common architecture uses Context for theme/auth and a store or data layer for everything busy.

The Redux questions and state management questions expand this decision.

Interview note: Follow-up: "can you build selectors on top of Context?" Not natively — libraries exist that add selector-style subscription to Context, but at that point a purpose-built store is usually the cleaner choice.

Q7. How do you combine Context with useReducer for app-wide state?

Hold the state with useReducer inside a Provider, then expose the state and dispatch through Context. Components read state from one context and dispatch actions from another (or the same), giving a lightweight Redux-like pattern without the library — suitable for medium apps with moderate update frequency.

const StateContext = createContext(null);
const DispatchContext = createContext(null);

function Store({ children }) {
  const [state, dispatch] = useReducer(reducer, initial);
  return (
    <StateContext.Provider value={state}>
      <DispatchContext.Provider value={dispatch}>{children}</DispatchContext.Provider>
    </StateContext.Provider>
  );
}

Splitting state and dispatch into two contexts is deliberate: dispatch is stable, so components that only dispatch never re-render on state changes.

Interview note: Follow-up: "why two contexts here?" So dispatch-only components (buttons) don't re-render when state changes — dispatch's reference is stable, state's is not.

Q8. What are common Context mistakes interviewers watch for?

Passing an inline object/array as the value (new reference every render), putting fast-changing state in a wide context, using Context where local state or composition would do, and forgetting the Provider so consumers silently get the default value. Each maps directly to a re-render or correctness bug, which is why they make good interview probes.

Interview note: Trap: "your useContext returns the default value in production — what happened?" A consumer rendered outside its Provider; wrap the subtree correctly, or throw from a custom hook when the context is null to fail loudly.

Q9. How do you make a safe custom hook around a Context?

Wrap useContext in a custom hook that throws a clear error when the context is missing, so misuse fails loudly instead of silently returning a default. This is a small idiom that reads as production experience.

function useAuth() {
  const ctx = useContext(AuthContext);
  if (ctx === null) throw new Error("useAuth must be used within <AuthProvider>");
  return ctx;
}

Interview note: Follow-up: "why throw instead of returning the default?" A silent default hides a wiring bug that surfaces as confusing behaviour later; throwing turns it into an immediate, obvious error.

How to prepare

Build an auth or theme context end to end: createContext, a Provider with a memoized value, a useContext consumer, and a safe custom hook — then deliberately introduce the inline-value bug and watch everything re-render in the Profiler. Seeing the re-render cascade once fixes the concept permanently. Rehearse the "Context is a transport, not a store" framing and the split-context fix, since those are the highest-value answers. Pair this with the state management and Redux sets for the tool-choice rounds, refresh patterns via the React learning path, and use a mock interview to practise the performance follow-ups out loud.

Frequently Asked Questions

What problem does the Context API solve?
It lets you pass data to deeply nested components without prop drilling — threading a prop through many intermediate components that do not use it. It suits global-ish data like theme, authenticated user and locale.
Why do all consumers re-render when context changes?
A component that calls useContext subscribes to the whole context value; when the Provider's value changes by reference, every consumer re-renders. There is no built-in way to subscribe to only part of the value, which is why fast-changing data is a poor fit.
How do you stop unnecessary Context re-renders?
Memoize the value passed to the Provider so it keeps a stable reference, split one large context into several focused ones, and separate rarely-changing data from frequently-changing data so consumers subscribe to only what they need.
Is Context a replacement for Redux?
No. Context is a transport for a value, not a store. It has no selectors, middleware or devtools and re-renders all consumers on change. For large, frequently-updated shared state, a store like Redux or Zustand with selective subscription fits better.
Can you have multiple contexts in one app?
Yes, and you usually should. Multiple focused contexts (auth, theme, locale) are better than one giant context because a change to one no longer re-renders consumers of the others.

Want to Build Your Career in Java Full Stack with AI?

Join CodeBegun and train with working industry engineers — Check the Java Full Stack training details

Apply for Demo Class →
Siva Prasad Galaba
Founder, CodeBegun · Staff Engineer

Founder of CodeBegun. 15+ years building Java systems at companies like Crunchyroll. Teaches Java, Spring Boot and system design the way the industry actually works, and mentors students through projects, mock interviews and placement preparation.

Technically reviewed by CodeBegun Technical TeamLast reviewed 16 July 2026 LinkedIn
Chat with us