React Mastery / Advanced React Hooks

Multiple Context

When your application grows, a single "Global Context" becomes a performance bottleneck and a maintenance nightmare. Handling multiple contexts effectively is about modularity and separation of concerns.


❓ Why Use Multiple Contexts?

  • Performance: React re-renders all consumers of a context when its value changes. By splitting context, a change in Theme won't force a re-render of the Auth logic.

  • Maintainability: Keeping CartContext separate from UserContext makes the code easier to read and debug.

  • Reusability: You can move specific contexts (like a ThemeContext) between projects easily.


🔴 The Context Composition Pattern

The standard way to handle multiple contexts is to "nest" the providers. However, this can lead to the "Provider Wrapper Hell."

The "Nested" Approach (Standard)

function App() {
  return (
    <AuthProvider>
      <ThemeProvider>
        <CartProvider>
          <MainLayout />
        </CartProvider>
      </ThemeProvider>
    </AuthProvider>
  );
}

✅ Solving "Wrapper Hell" with a Provider Composer

If you have 5+ contexts, your App.js becomes hard to read. You can create a utility component to flatten the structure.

Create a Composer Component

const ContextComposer = ({ providers, children }) => {
  return (
    <>
      {providers.reduceRight((acc, Provider) => {
        return <Provider>{acc}</Provider>;
      }, children)}
    </>
  );
};

Usage in App.js

function App() {
  return (
    <ContextComposer providers={[AuthProvider, ThemeProvider, CartProvider]}>
      <MainLayout />
    </ContextComposer>
  );
}

🧠 Consuming Multiple Contexts

In functional components, consuming multiple contexts is clean and straightforward using hooks.

function Header() {
  // You can call as many hooks as you need
  const { user } = useAuth();
  const { theme } = useTheme();
  const { itemCount } = useCart();

  return (
    <header className={theme}>
      <p>Hello, {user.name}. You have {itemCount} items in your cart.</p>
    </header>
  );
}

🚀 Performance Checklist

When handling multiple contexts, keep these rules in mind to prevent lag:

  1. Split by Frequency of Change: Don't put "Static Data" (Company Info) in the same context as "Volatile Data" (Real-time stock prices).

  2. Memoize Values: Use useMemo for the context value to prevent unnecessary re-renders when the parent component re-renders.

    const value = useMemo(() => ({ user, login, logout }), [user]);
  3. Specific Consumers: Ensure components only subscribe to the context they actually need.



💊 Summary Table

Feature

Single Mega-Context

Multiple Focused Contexts

Render Speed

Slower (everything updates)

Faster (only relevant parts update)

Code Organization

Messy / Bloated

Organized / Modular

Logic Scoping

Hard to track state logic

Logic is isolated to specific domains