Context in ReactJS Applications

  • The short answer is that you should very rarely, if ever use context in your own React components.
  • Context acts like a portal in your application in which components can make data available to other components further down the tree without being passed through explictly as props.
  • If an interim component does this, a child component won’t update, even if a context value changes:

    In the above example, if changes, will not render, because its parent returned from .

  • Libraries like React Router use context to allow the components that they provide application developers to communicate.
  • It exposes the object on the context, and other than that it simply renders the children that it’s given:

    expects to find , and it registers itself when it’s rendered:

    Finally, we can use the and components in our own app:

    The beauty of context in this situation is that as library authors we can provide components that can work in any situation, regardless of where they are rendered.

There is a lot of confusion amongst React developers on what context is, and why it exists. It’s also a feature that’s been hidden in the React documentation in the past and, although it is now documented on the React site I thought a post on its usage and when to use it would be of use.

@reactnewsletter: “How, when and why to use (or not use) context in ReactJS”

There is a lot of confusion amongst React developers on what context is, and why it exists. It’s also a feature that’s been hidden in the React documentation in the past and, although it is now documented on the React site I thought a post on its usage and when to use it would be of use.

The short answer is that you should very rarely, if ever use context in your own React components. However, if you’re writing a library of components, it can come in useful, and we’ll discuss why this is later.

What is context in React, and how does it work?

, for short. Parent components can pass properties down to their children:

If a child component wants to communicate back to its parent, it can do so through props, most commonly by its parent providing a callback property that the child can call when some event happens:

function comes from, who calls it, and which two components are in communication. You can see this in action on CodePen.

This property of React, its explicitness of data passing between components, is one of its best features. React is very explicit as a rule, and this is in my experience leads to clearer code that’s much easier to maintain and debug when something goes wrong. You simply have to follow the path of props to find the problem.

This diagram shows how props keep communication clear but can get a little excessive as you gain many layers in your application; each component has to explictly pass props down to any children.

. The components in between will probably have no use the these props and should probably not even know about them. When this situation arises, you can consider using React’s context feature.

Context acts like a portal in your application in which components can make data available to other components further down the tree without being passed through explictly as props.

When a component defines some data onto its context, any of its descendants can access that data. That means any child further down in the component tree can access data from it, without being passed it as a property. Let’s take a look at context in action.

First, on the parent component, we define two things:

on its context:

There’s a few reasons why you would want to avoid using context in your own code.

1. Hard to find the source.

Imagine that you’re working on a component on a large application that has hundreds of components. There’s a bug in one of them, so you go hunting and you find some component that uses context, and the value it’s outputting is wrong.

The bug is related to the click event not updating the right value, so you now go looking for the definition of that function. If it was being passed as a property, you could go immediately to the place where this component is rendered (which is usually just a case of searching for its name), and start debugging. In the case that you’re using context, you have to search for the function name and hope that you find it. This could be found easily, granted, but it also could be a good few components up the chain, and as your apps get larger the chances of you finding the source quickly gets smaller.

It’s similar to the problem when you work in an object oriented language and inherit from classes. The more classes you inherit from (or in React, the further down the component tree you get), it’s harder to find the source for a particular function that’s been inherited.

2. Binds components to a specific parent

A component that expects only properties (or no properties at all) can be used anywhere. It is entirely reusable and a component wanting to render it need only pass in the properties that it expects. If you need to use the component elsewhere in your application you can do easily; just by supplying the right properties.

However, if you have a component that needs specific context, you couple it to having to be rendered by a parent that supplies some context. It’s then harder to pick up and move, because you have to move the original component and then make sure that its new parent (or one of its parents) provides the context required.

3. Harder to test

prop:

to have a specific piece of context:

It’s harder here because we have to build the right parent component – it’s messier and quite verbose just to set up the component in the right context for testing.

4. Unclear semantics around context value changes and rerenders.

With properties and state, it’s very clear to React when it should rerender a component:

if it knows that it doesn’t need to be re-rendered. If an interim component does this, a child component won’t update, even if a context value changes:

is perfect. Another famous library that makes use of context is react-redux. I encourage you to look through the source code for both React Router and React Redux, you can learn a lot about React by doing so.

components can pick up on it and use it to function as expected.

property, indicating the path that they should match before rendering.

object on the context, and other than that it simply renders the children that it’s given:

, and it registers itself when it’s rendered:

components in our own app:

, it doesn’t matter at what level, and we don’t tie application developers to a specific structure.

Hopefully this blog post has shown you how and when to use context in React, and why more often than not you’d be better eschewing it in favour of props.

Thank you to the following blog posts and documentation for providing great material whilst putting this blog post together:

Thank you also to Arnaud Rinquin for taking the time to review this post.

Context in ReactJS Applications