Effects and essential hooks · Lesson 14 of 21
Context: data for the whole tree
createContext, Provider and useContext, and the end of prop drilling.
9 minutes2 games
When data like the theme, the current user or the language is needed by many components in different places, passing it as props from parent to child to grandchild is tedious: prop drilling. Context lets any component below a Provider read the value directly.
React
const ThemeContext = createContext("light")
function Button({ children }) {
const theme = useContext(ThemeContext)
const dark = theme === "dark"
return (
<button style={{ background: dark ? "#111" : "#eee", color: dark ? "#fff" : "#111", padding: "6px 12px", borderRadius: 8 }}>
{children}
</button>
)
}
function Toolbar() {
return <div><Button>Save</Button> <Button>Share</Button></div> // no theme prop here
}
function App() {
const [theme, setTheme] = useState("light")
return (
<ThemeContext.Provider value={theme}>
<label>
<input type="checkbox" checked={theme === "dark"} onChange={(e) => setTheme(e.target.checked ? "dark" : "light")} /> Dark
</label>
<Toolbar />
</ThemeContext.Provider>
)
}- ThemeContext.Provider value="dark"
- Toolbar (doesn't touch theme)
- Button → useContext → "dark"
- Button → useContext → "dark"
- Toolbar (doesn't touch theme)
Toolbar knows nothing about the theme; the buttons reach it directly.
What's the output?
const Lang = createContext("ar")
function Label() {
return <span>{useContext(Lang)}</span>
}
function App() {
return (
<div>
<Label />
<Lang.Provider value="en">
<Label />
<Lang.Provider value="fr">
<Label />
</Lang.Provider>
</Lang.Provider>
</div>
)
}What will the page show?
Exercise
Create a UserContext; App wraps everything in a Provider with { name: "Nour", xp: 410 }. The Navbar component (no props) shows Nour · 410 xp.
The page should show: Nour · 410 xp
React
function Navbar() {
return <nav>Guest</nav>
}
function App() {
return <Navbar />
}Learn more from
Played 0 of 2 games
Sign in to save your progress and earn XP.