REACT Context API

The React Context API is a tool for managing state globally in a React application. It allows you to share values (like state or functions) between components without passing props manually down through the component tree.

Why Use Context API?

  • To avoid “prop drilling” (passing props through multiple levels of components).
  • To manage global state (e.g., user authentication, themes, or application settings).
  • It’s simpler and lighter than state management libraries like Redux for certain use cases.

How Does the Context API Work?

The Context API has three main components:

  1. Context Provider: Supplies the data to components.
  2. Context Consumer: Consumes the data from the provider.
  3. React.useContext Hook: Simplifies consuming the context.

Basic Steps to Use Context API

1. Create a Context

import React, { createContext } from 'react';

const MyContext = createContext(); // Create the context
export default MyContext;

Try It Now

2. Provide the Context

Wrap your components with the context Provider and pass the value to share.

import React, { useState } from 'react';
import MyContext from './MyContext';

const App = () => {
  const [user, setUser] = useState('John Doe');

  return (
    <MyContext.Provider value={{ user, setUser }}>
      <Child />
    </MyContext.Provider>
  );
};

const Child = () => {
  return <Grandchild />;
};

const Grandchild = () => {
  return <p>I am the grandchild component.</p>;
};

export default App;

Try It Now

3. Consume the Context

There are two ways to consume the context:

  1. Using useContext Hook (Recommended for Functional Components):
    import React, { useContext } from 'react';
    import MyContext from './MyContext';
    
    const Grandchild = () => {
      const { user } = useContext(MyContext);
    
      return <p>Logged-in user: {user}</p>;
    };
    

    Try It Now

  2. Using the Consumer Component (Older Method):
    import React from 'react';
    import MyContext from './MyContext';
    
    const Grandchild = () => {
      return (
        <MyContext.Consumer>
          {({ user }) => <p>Logged-in user: {user}</p>}
        </MyContext.Consumer>
      );
    };
    

    Try It Now

Real-World Example: Theme Context

1. Create the Context

import React, { createContext, useState } from 'react';

const ThemeContext = createContext();

export const ThemeProvider = ({ children }) => {
  const [theme, setTheme] = useState('light');

  const toggleTheme = () => {
    setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light'));
  };

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};

export default ThemeContext;

Try It Now

2. Use the Provider in the App

import React from 'react';
import { ThemeProvider } from './ThemeContext';
import ThemeToggler from './ThemeToggler';

const App = () => {
  return (
    <ThemeProvider>
      <ThemeToggler />
    </ThemeProvider>
  );
};

export default App;

Try It Now

3. Consume the Context

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

const ThemeToggler = () => {
  const { theme, toggleTheme } = useContext(ThemeContext);

  return (
    <div>
      <p>Current Theme: {theme}</p>
      <button onClick={toggleTheme}>Toggle Theme</button>
    </div>
  );
};

export default ThemeToggler;

Try It Now

When to Use Context API

  • Use for global state like:
    • Themes (light/dark mode)
    • User authentication (logged-in user data)
    • Language preferences (i18n)
  • Avoid using it for frequent updates or performance-critical data (use local state or libraries like Redux or Zustand).

Best Practices

  1. Avoid Overusing Context: Don’t replace local state with context unless needed.
  2. Split Contexts: Use multiple contexts for unrelated data (e.g., one for theme, one for user).
  3. Memoize Values: Use useMemo for derived values in the provider to avoid unnecessary re-renders.
    const value = useMemo(() => ({ user, setUser }), [user]);
    <MyContext.Provider value={value}>{children}</MyContext.Provider>;
    

    Try It Now

  4. Combine with Other Tools: Use alongside tools like React.memo or React.lazy for optimized performance.