React useContext Hook: Beginner’s Guide with Examples
In React, props are used to pass data from parent to child components. But in large applications, passing props through multiple levels can become cumbersome.
The useContext Hook allows you to:
Share data globally across multiple components
Avoid “prop drilling” (passing props through layers unnecessarily)
Make your app easier to maintain
Think of useContext as a global store for specific data, without the need for complex state management libraries.
How useContext Works
Create a Context →
React.createContext()Provide the Context →
<Context.Provider>wraps components that need accessConsume the Context →
useContext(MyContext)in child components
Example 1: Basic useContext
Create Context
import React, { createContext } from "react"; export const ThemeContext = createContext();Provide Context
import { ThemeContext } from "./ThemeContext";
function App() {
const theme = "dark";
return (
<ThemeContext.Provider value={theme}>
<Toolbar />
</ThemeContext.Provider>
);
}
Consume Context
import { useContext } from "react";
import { ThemeContext } from "./ThemeContext";
function Toolbar() {
const theme = useContext(ThemeContext);
return <h1>Current Theme: {theme}</h1>;
}
Output:
Current Theme: darkExample 2: Sharing Objects with Context
const UserContext = React.createContext();
function App() {
const user = { name: "John", age: 25 };
return (
<UserContext.Provider value={user}>
<Profile />
</UserContext.Provider>
);
}
function Profile() {
const user = useContext(UserContext);
return (
<div>
<h2>Name: {user.name}</h2>
<p>Age: {user.age}</p>
</div>
);
}
Context can store objects, arrays, or any value.
useContextgives direct access to the value without prop drilling.
Example 3: Nested Components
function App() {
const language = "React";
return (
<LanguageContext.Provider value={language}>
<Parent />
</LanguageContext.Provider>
);
}
function Parent() {
return <Child />;
}
function Child() {
const language = useContext(LanguageContext);
return <h1>Learning: {language}</h1>;
}
Even if
Childis nested deeply, it can directly consume the context.Eliminates the need to pass props through
Parent.
Best Practices for useContext
| Practice | Explanation |
|---|---|
| Keep context focused | One context per domain (e.g., ThemeContext, UserContext). |
| Avoid frequent updates | Updating context often can cause performance issues. |
| Combine with useReducer | For complex state logic in global context. |
| Default values | Provide meaningful default values for safety. |
| Do not abuse | Only use context for data that truly needs to be global. |
FAQ
Q1: Can I update the context value?
Yes, by storing the value in state (useState) and passing it to <Provider value={state}>.
Q2: Can I have multiple contexts?
Yes! You can wrap components with multiple Providers.
Q3: Does useContext replace Redux?
Not fully. Context is best for small to medium apps. For large, complex global state, consider Redux or Zustand.