// Passing 'user' through every level, even components that don't need it themselves
function App() {
const user = { name: "Ravi" };
return <Layout user={user} />;
}
function Layout({ user }) {
return <Sidebar user={user} />;
}
function Sidebar({ user }) {
return <UserBadge user={user} />;
}
function UserBadge({ user }) {
return <p>{user.name}</p>;
}Layout and Sidebar don't actually use user themselves โ they're just passing it through. This chain becomes unmanageable as an app grows.
import { createContext, useContext } from "react";
const ThemeContext = createContext("light");
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
return <Button />; // no props needed here at all!
}
function Button() {
const theme = useContext(ThemeContext);
return <button className={theme}>Save</button>;
}Toolbar doesn't touch theme at all โ Button reaches directly into the Context using useContext, completely skipping the intermediate component.
Every component that consumes a Context re-renders whenever that Context's value changes โ even if the specific piece of data they use didn't actually change. For state that updates very frequently (like mouse position), Context isn't the right tool; it's best suited for genuinely global, relatively infrequently-changing data like the current theme, logged-in user, or language preference.
Not every shared value needs Context โ for state used by only two or three closely related components, simple prop passing or lifting state up (Chapter 18) is often clearer and has fewer performance trade-offs. Reach for Context specifically when a value is needed by many components at very different nesting depths.
Build an AuthContext that provides a logged-in username to a deeply nested component, without passing it through any intermediate components as a prop.
import { createContext, useContext } from "react";
const AuthContext = createContext(null);
function App() {
return (
<AuthContext.Provider value={{ username: "Priya" }}>
<Dashboard />
</AuthContext.Provider>
);
}
function Dashboard() {
return <Profile />;
}
function Profile() {
const { username } = useContext(AuthContext);
return <p>Logged in as {username}</p>;
}
Q Can I have multiple different Contexts in one app?
Yes โ most real apps have several, one each for theme, authenticated user, language/locale, and so on. Each is created and provided independently, and a component can consume as many of them as it needs.
Q Does using Context replace the need for state entirely?
No โ Context is a way to share existing state across components without prop drilling; the state itself still needs to be created somewhere, typically with useState or useReducer in the component that provides the Context.