Context and Shared State
💻 ReactShare state across components without passing props through every level.
When many components need the same value, props become noisy. Context provides it to a whole subtree.
- Create a context.
- Provide a value.
- Read context with useContext.
Create a Context
A context holds a value that any descendant can read. Provide it once near the top of the tree.
import { createContext, useContext, useState } from "react";
const ThemeContext = createContext(null);
export function ThemeProvider({ children }) {
const [theme, setTheme] = useState("light");
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
export function useTheme() {
const value = useContext(ThemeContext);
if (!value) throw new Error("useTheme must be used inside ThemeProvider");
return value;
}Using It
Any descendant can read and update the theme without receiving props.
function ThemeToggle() {
const { theme, setTheme } = useTheme();
return (
<button => setTheme(theme === "light" ? "dark" : "light")}>
Switch to {theme === "light" ? "dark" : "light"}
</button>
);
}When Not to Use Context
Context is not a replacement for every state. Keep local state local. Use context for values that are genuinely global, such as the current user, theme or language.
Practice
- Create a user context with a name and a logout function.
- Read the context in a nested component.
- Explain why local state is better for a single form.
Hands-on exercise
Create a CartContext that holds an array of items and an addItem function.
Provide it at the app root.
Build a button component that adds a product and a header that shows the item count.
Recap
Context shares state across a subtree. Use it for genuinely global values and keep local state local.
Example
import { createContext, useContext, useState } from "react";
const ThemeContext = createContext(null);
export function ThemeProvider({ children }) {
const [theme, setTheme] = useState("light");
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}
export function useTheme() {
const value = useContext(ThemeContext);
if (!value) throw new Error("useTheme must be used inside ThemeProvider");
return value;
}
Exercises
Provide it at the app root.
Build a button component that adds a product and a header that shows the item count.
Expected Output
A shared cart count that updates from a button anywhere in the tree.
Lesson Nav
React Course
0/9 lessons completed
- 1 Thinking in Components Tutorial
- 2 Props and Composition Tutorial
- 3 State and Events Tutorial
- 4 Lists, Keys and Conditional Rendering Tutorial
- 5 Forms in React Tutorial
- 6 Effects and Data Fetching Tutorial
- 7 Routing and Layouts Tutorial
- 8 Context and Shared State Tutorial
- 9 Project: A Student Dashboard Project