In a typical React application, data is passed top-down (parent to child) via props. However, certain types of data are needed by almost every component in the entire tree—such as the currently logged-in user profile, an active dark/light visual theme, or a shopping cart total.
Passing this data through 10 intermediate components that do not care about it is called Prop Drilling. The React Context API completely eliminates this by broadcasting data across the entire subtree.
Figure 7: Context Teleportation: Components directly consume state without touching intermediate ancestors.
The modern industry best practice is to encapsulate context creation, state logic, and a custom consumer hook into a dedicated file:
// src/context/AuthContext.jsx
import React, { createContext, useContext, useState } from 'react';
// 1. Create Context Object
const AuthContext = createContext(null);
// 2. Custom Provider Component
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState({ name: 'Vikram', role: 'Student' });
const login = (userData) => setCurrentUser(userData);
const logout = () => setCurrentUser(null);
return (
<AuthContext.Provider value={{ currentUser, login, logout }}>
{children}
</AuthContext.Provider>
);
}
// 3. Custom Consumer Hook for Clean Access
export function useAuth() {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within an AuthProvider!');
}
return context;
}
// src/App.jsx
import { AuthProvider } from './context/AuthContext';
import Navbar from './components/Navbar';
import UserProfile from './components/UserProfile';
function App() {
return (
<AuthProvider>
<Navbar />
<UserProfile />
</AuthProvider>
);
}
// Deeply nested child component: src/components/UserProfile.jsx
import { useAuth } from '../context/AuthContext';
function UserProfile() {
const { currentUser, logout } = useAuth();
if (!currentUser) return <p>Please log in.</p>;
return (
<div className="profile-card">
<h3>Logged in as: {currentUser.name}</h3>
<p>Account Level: {currentUser.role}</p>
<button onClick={logout}>Sign Out</button>
</div>
);
}
When state logic becomes complex with multiple interrelated actions, let us master React useReducer Hook.
Accelerate your React mastery by studying these tightly connected core tutorials:
Why Context API is required in deeply nested trees.
Building lightweight Redux-like global stores.
Avoiding Context re-render performance bottlenecks.