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:
- Context Provider: Supplies the data to components.
- Context Consumer: Consumes the data from the provider.
- 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;
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;
3. Consume the Context
There are two ways to consume the context:
- Using
useContextHook (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>; }; - 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> ); };
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;
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;
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;
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
- Avoid Overusing Context: Don’t replace local state with context unless needed.
- Split Contexts: Use multiple contexts for unrelated data (e.g., one for theme, one for user).
- Memoize Values: Use
useMemofor derived values in the provider to avoid unnecessary re-renders.const value = useMemo(() => ({ user, setUser }), [user]); <MyContext.Provider value={value}>{children}</MyContext.Provider>; - Combine with Other Tools: Use alongside tools like
React.memoorReact.lazyfor optimized performance.