How to use the useContext React hook
By Flavio Copes
Learn how to use the useContext React hook to read the current value from the nearest context provider and re-render the component when that value changes.
Check out my React hooks introduction first, if you’re new to them.
The useContext hook lets a component read a value that a parent component placed in a React context, without passing it down as a prop through every level in between.
import { useContext } from 'react'
This hook is used in combination with the React Context API.
Why does context exist?
Say the top of your app knows the current theme, and a button 5 levels down needs it. Without context, every component in between must accept a theme prop and hand it to its child, even if it never uses it. This is called prop drilling.
Context skips the middlemen. A parent provides a value, and any component below can read it directly.
How to use it
First, create a context. This usually lives in its own file, so both sides can import it:
import { createContext } from 'react'
const ThemeContext = createContext('light')
The 'light' argument is the default value, used when no provider is found.
Then wrap a part of your tree with the provider, passing the value. Since React 19, the context itself is the provider:
<ThemeContext value="dark">
<Toolbar />
</ThemeContext>
In older code you’ll see <ThemeContext.Provider value="dark"> instead. It still works, but React plans to deprecate it in a future version. I listed this change with the others in what’s new in React 19.
Finally, call useContext in any component inside that tree to get the current context value:
const theme = useContext(ThemeContext)
which refers to the nearest <ThemeContext> provider above in the tree. In this example, theme is 'dark'.
Calling useContext will also make sure the component rerenders when the context value changes.
One pitfall
If there’s no provider above the component, useContext doesn’t throw. It silently returns the default value you passed to createContext().
That can hide bugs. You forget to wrap your app with the provider, everything renders with 'light', and no error points you at the cause. When you see the default value where you expect real data, check your providers first.
Also, every component reading a context re-renders when its value changes. Context works best for data that changes rarely, like the theme or the logged in user.
What about use()?
React 19 also added use(), and it can read a context too:
import { use } from 'react'
function Heading({ children }) {
if (!children) {
return null
}
const theme = use(ThemeContext)
return <h1 className={theme}>{children}</h1>
}
The difference is that you can call use() inside an if or a loop. You can’t do that with useContext, because hooks must run at the top of the component.
You don’t need to switch. useContext is still the right tool for most components.
I recommend you to read my Context API tutorial to know more about it.
Want me to talk about your product? You can sponsor this site.