Skip to content

React Context API Interview Guide

Context API is a built-in React feature used to share data across multiple components without passing props manually at every level (prop drilling).

Common use cases:

  • Theme (Dark/Light mode)
  • Authentication
  • User preferences
  • Language settings
  • Global state
const UserContext = React.createContext();

It solves prop drilling.

Without Context:

App -> Parent -> Child -> GrandChild

Every component passes props even if it doesn’t use them.

With Context:

GrandChild
->
useContext(UserContext)

Direct access to shared data.

import { createContext } from "react";
const UserContext = createContext();

Supplies data to components.

<UserContext.Provider value={user}>
<App />
</UserContext.Provider>

Reads context values.

<UserContext.Consumer>
{(user) => <h1>{user.name}</h1>}
</UserContext.Consumer>

Today, useContext() is generally preferred.

The useContext hook consumes context values.

const user = useContext(UserContext);

Benefits:

  • Cleaner code
  • No nested Consumer components
flowchart TD
    A[Create Context] --> B[Provider supplies value]
    B --> C["Child calls useContext()"]
    C --> D[Receives latest value]
const ThemeContext = createContext();
function App() {
return (
<ThemeContext.Provider value="dark">
<Home />
</ThemeContext.Provider>
);
}
function Home() {
const theme = useContext(ThemeContext);
return <h1>{theme}</h1>;
}

Use it for:

  • Authentication
  • Theme
  • Locale
  • User profile
  • Shared settings

Avoid using it as the primary solution for frequently changing, complex application state.

  • Re-render issues
  • Not ideal for complex state management
  • Harder debugging than Redux
  • No middleware support

When the Provider value changes:

<UserContext.Provider value={user}>

all consuming components re-render, even if they only use a small part of the object.

Example:

{
name: "John",
age: 25
}

Changing age still causes every consumer to re-render.

const value = useMemo(() => ({
user,
updateUser
}), [user]);
<UserContext.Provider value={value}>

This prevents creating a new object on every render.

Can React.memo Prevent Context Re-renders?

Section titled “Can React.memo Prevent Context Re-renders?”

No.

const Child = React.memo(() => {
const user = useContext(UserContext);
});

Context updates bypass React.memo because React directly notifies context subscribers.

Context API Redux
Built into React External library
Simple state sharing Complex state management
No middleware Middleware support
Re-renders consumers Better optimization
Small apps Large apps
Prop Drilling Context API
Pass props through many levels Direct access
Hard to maintain Easier maintenance
More boilerplate Less code
Higher component coupling Cleaner architecture
<AuthContext.Provider>
<ThemeContext.Provider>
<App />
</ThemeContext.Provider>
</AuthContext.Provider>

Consume:

const auth = useContext(AuthContext);
const theme = useContext(ThemeContext);

If useContext is called outside a matching Provider, it returns the default value.

const UserContext = createContext("Guest");

Output:

Guest
const AuthContext = createContext();
function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const login = () => {};
const logout = () => {};
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
}
  • Split contexts (UserContext, ThemeContext, LanguageContext)
  • Use useMemo
  • Use context selectors (useContextSelector) where appropriate
  • Consider Redux, Zustand, or Recoil for complex state

Instead of deeply nesting providers:

<AuthProvider>
<ThemeProvider>
<LanguageProvider>
<App />
</LanguageProvider>
</ThemeProvider>
</AuthProvider>

Create:

<AppProviders>
<App />
</AppProviders>

This improves readability.

Why Context API Is Not Full State Management

Section titled “Why Context API Is Not Full State Management”

Context only shares state.

It does not provide:

  • Middleware
  • DevTools
  • Time-travel debugging
  • State normalization
  • Advanced caching
  • Optimized selective subscriptions

Large applications commonly use Redux Toolkit, Zustand, MobX, or Recoil alongside or instead of Context.

  • Context API solves prop drilling.
  • Provider supplies data; useContext consumes it.
  • Provider value changes re-render all consumers.
  • React.memo does not prevent context-driven re-renders.
  • Use useMemo and split contexts for better performance.
  • Context is a state-sharing mechanism, not a complete state management solution.
  • Context API is ideal for sharing global UI state such as authentication, themes, and localization.
  • It simplifies component communication by eliminating prop drilling.
  • Performance should be considered because Provider updates re-render consumers.
  • Optimize with useMemo, smaller contexts, and appropriate state management libraries for large applications.