Context is a powerful API to pass state within React applications, and with the introduction of the useContext Hook, accessing state in any component (class or functional) is possible.
useContext Hook simplifies using the Context API within a React application, even in functional components.
For the longest time, I understood why Context existed: to avoid passing props through React components that didn't need them to reach the components that did need them.
But what I couldn't wrap my head around was how to not only consume the already-defined state context at the child component level but also update that same state in the parent component from the child.
When I finally figured that out, things clicked into place for me. And the first time I really started to take advantage of Context was with the release of the
In this lesson, we'll learn how the
useContext Hook can be employed to simplify passing state around within a React application.
Sample useContext code#
My code example for this lesson is a multi-file example to illustrate how
useContext could work in a real-world scenario.
In it, a context is created to capture state in a parent component. An intermediate component (that does not need that parent's state) contains a functional child component that does rely on the parent's state and also needs to update it.
useContext helps make this possible.
useContext to allow functional child components to consume and update parent state#
In this example, after the app initially loads, when you click the Open Drawer from Parent button, you'll see a purple background pop up (the drawer, in this case) with a new button titled Close Drawer from Child.
If you've used Context before, you may already be pretty familiar with how it operates, but let's briefly discuss how
useContext works as a hook, then we'll go through the various pieces of the code and connect the dots.
How does useContext work?#
useContext Hook accepts a Context object (the value returned from calling
React.createContext) and returns the current context value for that Context. The current context value is determined by the value prop of the nearest
<SampleContext.Provider> above the calling component in the tree.
When the nearest
<SampleContext.Provider> above the component updates, this hook will trigger a re-render with the latest context value passed to that
If the above paragraphs sounded like a lot of jargon to you, never fear. The next section explains what I'm describing step by step with code examples.
The argument passed to the
useContext Hook must be the context object itself. And just like with all the other React Hooks, you can use multiple different Contexts within the same functional component.
Multiple useContext Hooks in one child component
Any component calling the same
useContextdata source will always re-render when the provider's context value changes.
What this means is: if you've got two components subscribed to the same Provider and one component updates the Provider's value, both of those components will re-render. Don't worry too much about this now, but do be aware that it will happen.
If re-rendering the component is expensive, you can optimize it using React's useMemo Hook. But that's beyond the scope of this lesson (and frankly, only to be undertaken once performance actually becomes a problem).
All right, let's get into the
useContext code example now.
First, check out the DrawerContext.js file#
The first file to look at is the
DrawerContext.js. As stated above, a Context object is created by invoking
React.createContext, then wrapping the new context around the parent component providing the values to the context.