React Mastery / Advanced React Hooks

Context Api & useContext hook

❓ What is Context in React?

The Context API is a built-in React feature designed to solve the problem of "prop drilling"—the tedious process of passing data through multiple layers of components that don't actually need it.

Think of it as a "global state" for a specific tree of components.

🔴 What is Prop drilling?

Passing data through many layers of components just to reach a deeply nested component.

This makes code:

  • Hard to read

  • Hard to maintain

  • Error-prone

<aside>

💡The Context API solves the issue of prop drilling in React

</aside>


✅ Core Concepts

To master Context, you need to understand three primary pillars:

  1. The Context Object: Created using createContext(). This holds the default value.

  2. The Provider: A component that "broadcasts" the state to its children.

  3. The Consumer: Any component within the Provider’s tree that "tunes in" to the state (usually via the useContext hook).


🧠 Implementation Workflow

1. Create the Context

Start by initializing the context. It’s best practice to do this in a separate file.

ThemeContext.js

import { createContext } from 'react';

// You can provide a default value (e.g., 'light') 
export const ThemeContext = createContext('light');

2. Provide the Value

Wrap your component tree with the Provider. Every component inside this wrapper can now access the value prop.

App.js

import { ThemeContext } from './ThemeContext.js';

function App() {
  const [theme, setTheme] = useState('dark');

  return (
    <ThemeContext.Provider value={theme}>
      <Dashboard /> 
    </ThemeContext.Provider>
  );
}

3. Consume the Value

In any nested component, use the useContext hook to grab the data.

Button.js

import { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

function Button() {
  const theme = useContext(ThemeContext);
  return <button className={theme}>Click Me</button>;
}

❓ When to Use vs. When to Avoid

Use Context For...

Avoid Context For...

Theming: Dark/Light mode settings.

High-frequency updates: Data that changes every millisecond (like a mouse tracker).

User Auth: Storing the logged-in user's profile.

Local state: If only two closely related components need the data, stick to props.

Localization: Preferred language or currency.

Complex Logic: If state logic becomes massive, consider Redux or Zustand.


🚀 Performance Optimization

One common pitfall is that every component consuming a context re-renders whenever the context value changes. To mitigate this:

  • Split Contexts: Don't put your entire app state in one giant "GlobalContext." Create separate contexts for Auth, Theme, and Settings.

  • Memoization: Wrap the value being passed into the Provider in useMemo so it doesn't create a new object reference on every render.

Pro Tip: If you find yourself nesting 5+ Providers in App.js, it’s time to create a "Provider Composer" component to keep your JSX clean.