Using Context in React
I had the opportunity to speak at React Conf 2018 about the new ways to use context in React. This blog post is a text version of my talk.
Check out the video of it on YouTube:
I’ve recently been helping out a startup called fl33t. It’s an over the air update service. For example, if you have a hardware device and need to update the software on it, you can use fl33t to deploy those software updates.
This is what the main dashboard looks like when you log in to fl33t.com. The fl33t application allows you to group your devices however you want — these groups are called fleets. For example, If you have a fleet of QA devices that need a specific software build, you can deploy the software to that fleet.
To create a new fleet, you click the “New Fleet” button which takes you to a multi-step form with four steps. Each step in this form is a different React component, and all of these components share a single parent component. Since I want to share data across this multi-step form, this is a good use case for using context.
It should be noted though that the context API isn’t meant to be used for every part of your application- it’s meant to be used for sharing data in a tree of React components. From the React documentation:
Context is designed to share data that can be considered “global” for a tree of React components
Before refactoring the code to use context, this is what the instances of the form components in the parent component (the FleetForm.js file) looked like:
You’ll notice a lot of data and functions are getting passed down via props. By using context, we will eliminate the need to pass data or functions down as props and just render the component.
To start out using the context API we create a file, and in that file, we call React.createContext() and save the result in a variable.
Next, in our parent component, we import the context object from that file.
In the case of this multi-step form, I want to share the state of the parent component and two functions that allow me to pass data back up to the parent component when the user interacts with a particular step in the form.
You might have noticed at the bottom of the state object that I’ve added two functions and wondering why those are there. In the render function of our parent component, we’ll wrap our components with a
Provider component. The
Provider component has a value prop — this is where we add any data we want to share with our child components.
There are some gotchas in using context — if I just added the two methods to an object like the above code for the value prop, it might unintentionally trigger a re-render in the child components because a new object will get created every time the Provider gets re-rendered.
Instead, we put the two methods in the state object and set the Provider value to
It’s a little bit funky, but it works.
For our child components to have access to the data we need to modify them slightly. As of right now, there are three different options for using context in an application.
With the release of version 16.3 of React earlier this year, the way to use context in connection with the
Providercomponent is to wrap your component in a
This is a valid way to use context, but there are a couple of more ergonomic ways of using context that were released this week, so let’s focus on these newer ways to use context.
In version 16.6 of React that was released on Tuesday, the class property
contextType was added to allow for a more straightforward way to use context. In the child component first, we import the context object.
Then, at the bottom of our class definition file, before we export it, we add the
contextType property and set it to the context object we imported at the top of our file.
By doing this we can now access data using
this.context For example, in one of the methods in one of the child components, we call
Now we refactor it to call
With the new announcement about hooks at React Conf, we now have a 3rd option for how to use context in our application. Since using hooks would require a significant refactor of the steps in my form — I’ll show you what I would do if I wanted to add another step to my form and instantly have access to all the form data and functions without having to pass props down.
First, we’ll import the
Next, we import the FleetContext object
Then, in our FleetFormStep5 function, we’ll call the
useContext hook which will give us access to the data from the parent component
Finally, we can use the context data and return our component
That’s all there is to it!
If you’re interested in learning more about React — you can purchase Fullstack React: The Complete Guide to ReactJS and Friends
And if you want to get weekly updates on all things React & React Native, sign up for my weekly newsletter — The Fullstack React Newsletter