useContext
useContext is a React Hook that lets you read and subscribe to context from your component.
Passing data deeply into the tree
Call useContext at the top level of your component to read and subscribe to context.
useContext returns the context value for the context you passed. To determine the context value, React searches the component tree and finds the closest context provider above for that particular context.
To pass context to a Button, wrap it or one of its parent components into the corresponding context provider:
function MyPage() {
return ();
}
It doesn’t matter how many layers of components there are between the provider and the Button. When a Button anywhere inside of Form calls useContext(ThemeContext), it will receive “dark” as the value.
useContext() always looks for the closest provider above the component that calls it. It searches upwards and does not consider providers in the component from which you’re calling useContext().
Updating data passed via context
Often, you’ll want the context to change over time. To update context, you need to combine it with state. Declare a state variable in the parent component, and pass the current state down as the context value to the provider.
function MyPage() {
const [theme, setTheme] = useState('dark');
return ( {
setTheme('light');
}}>
Switch to light theme);
}
Now any Button inside of the provider will receive the current theme value. If you call setTheme to update the theme value that you pass to the provider, all Button components will re-render with the new ‘light’ value.
Specifying a fallback default value
If React can’t find any providers of that particular context in the parent tree, the context value returned by useContext() will be equal to the default value that you specified when you created that context
The default value never changes. If you want to update context, use it with state as described above.
Overriding context for a part of the tree
You can override the context for a part of the tree by wrapping that part in a provider with a different value.
…
…
You can nest and override providers as many times as you need.
Optimizing re-renders when passing objects and functions
You can pass any values via context, including objects and functions.
function MyApp() {
const [currentUser, setCurrentUser] = useState(null);function login(response) {
storeCredentials(response.credentials);
setCurrentUser(response.user);
}
return (
);
}
Here, the context value is a JavaScript object with two properties, one of which is a function. Whenever MyApp re-renders (for example, on a route update), this will be a different object pointing at a different function, so React will also have to re-render all components deep in the tree that call useContext(AuthContext).
In smaller apps, this is not a problem. However, there is no need to re-render them if the underlying data, like currentUser, has not changed. To help React take advantage of that fact, you may wrap the login function with useCallback and wrap the object creation into useMemo. This is a performance optimization:
function MyApp() {
const [currentUser, setCurrentUser] = useState(null);const login = useCallback((response) => {
storeCredentials(response.credentials);
setCurrentUser(response.user);
}, []);
const contextValue = useMemo(() => ({
currentUser,
login
}), [currentUser, login]);
return (
);
}
The login function does not use any information from the render scope, so you can specify an empty array of dependencies. The contextValue object consists of currentUser and login, so it needs to list both as dependencies. As a result of this change, the components calling useContext(AuthProvider) won’t need to re-render unless currentUser changes.
Reference
useContext(SomeContext)
Call useContext at the top level of your component to read and subscribe to context.
Parameters
SomeContext: The context that you’ve previously created with createContext. The context itself does not hold the information, it only represents the kind of information you can provide or read from components.
Returns
useContext returns the context value for the calling component. It is determined as the value passed to the closest SomeContext.Provider above the calling component in the tree. If there is no such provider, then the returned value will be the defaultValue you have passed to createContext for that context. The returned value is always up-to-date. React automatically re-renders components that read some context if it changes.
Caveats
Troubleshooting
My component doesn’t see the value from my provider
I am always getting undefined from my context although the default value is different
// 🚩 Doesn’t work: no value prop
You may have also mistakingly used a different prop name by mistake:
Note that the default value from your createContext(defaultValue) call is only used if there is no matching provider above at all. If there is a component somewhere in the parent tree, the component calling useContext(SomeContext) will receive undefined as the context value.