Software systems to innovate and grow

What You Need to Know About the New React Context API

By Engineering Team December 10, 2018 10 mins read

The new React Context API is a massive change from the old version. It’s a much easier option for developers wanting to share data in many different parts of a React application. The legacy API is still available until the next major release (v17), but the React folks recommend switching if you are on 16.3 or higher, as it is the way forward. Besides, once you see what the shiny new Context can do, you won’t need any more convincing. First, let’s quickly define context as it relates to React and why you might want an API to manage it.

Getting Up to Speed on Context

Context is a nebulous concept in computer science and can depend on the type of programming being done. With React, context can be thought of as a means of transportation from a component’s props to any other component in the app.

Here’s an example:

Have you ever passed props through numerous nested components just so you could use it in a single child component? Context is the pipe through which those props travel.

The legacy API did an okay job of this, but it was pretty clunky and an explicit warning in the docs about not using it to update context, which scared many off its users away. Thus, the need for an upgrade. In any event, the need to share state anywhere without having to put it everywhere in a component tree is the driving purpose behind the context API and can be very convenient when you need it (e.g., when you need to pass props around to too many components at different nesting levels).

Note: It should be said here that using context may not be your best bet in all cases. If you just need to move props down a few levels in the tree, composition is almost always going to be the easier, less disruptive option.

The Nuts & Bolts of Context

Three things are needed to tap into the power of context:

  1. The context itself
  2. A context provider
  3. A context consumer

Context

With the new API, creating a provider and defining the data you want to share is very simple.

Let’s break this down.

The Provider and Consumer are created together by createContext. The defaultValue is not strictly required and will only be used by Consumers that are not connected to a Provider further up the tree.

Provider

The Provider is a React component that carries our data through the context pipe to any Consumer that is subscribed to it.

The value prop is what gets passed down the pipe to each subscriber. If you are familiar with Redux and its Provider, the concept is essentially the same. You can even use the Redux Provider pattern with React’s Provider, but that’s for another post.

Note: There’s been some chatter in the community about this replacing Redux, and while it is certainly possible, there are a lot of variables to consider before making that kind of move, i.e. the size of your app, your team’s skill set, time travel debugging, etc. Proceed carefully.

Consumer

Like Providers, Consumers are React components, as well. As mentioned earlier, they subscribe to a Provider further up the tree and gain access to its context, which exposes the data named in its value prop.

Consumers expect a function as a child. In fact, they have to have it. You might recognize it as the render props pattern, which is used throughout React itself, many of its libraries, and many React apps. Its value argument is the same as the Provider it subscribes to, returning a React node when called.

Note: Since Consumers are descendents of the Provider, any time the Provider’s value prop changes, all the Consumers subscribed to that Provider will re-render. This reaffirms the concept that these two components are functionally two parts of a whole, as you would have no use for one without the other.4

Basic Usage

So, how do we use this? Obviously, there are a ton of potential scenarios for sharing data in React, but let’s take a look at a simple example.

So, this pattern for setting up context is a little different than the one we saw above. See the variation?

Named Context

We’ve named our context LightContext, and while we don’t really need it in something this simple, connecting Providers and Consumers in this way keeps things organized, especially when you start using multiple contexts. Now, we can scan our file and see exactly where each context is being used, and because our Providers and Consumers are connected to LightContext via dot notation, the location of the Consumers in the tree is irrelevant. Remember, without this, they would simply subscribe to the Provider nearest to it in the tree.

Skipping Intermediate Elements

See how the LightContext jumps from App to LightSwitch, bypassing LightPanel all together? That’s the beauty of this new API. Extrapolate this example to five contexts and ten elements, and you start to understand why this is a big deal. Also, since Providers and Consumers are components, we are free to use them almost any way we want, including as objects, data stores, or higher-order components.

Wrapping Up

React’s new context is a pretty big leap forward and a huge boon for the community. Clearly, the team drew heavily from Redux’s functionality, but there’s nothing wrong with that as long as it makes sense and works well. And we think it does.

Such simplicity and flexibility has become the React trademark and is the main reason it continues to grow as the most popular JavaScript tool in the world. With the legacy API sunsetting in the near future, the time is now to get going with this, so jump in with both feet, and don’t be afraid to get creative.

Good luck, and keep coding!