Context

With React, it's easy to track the flow of data through your React components. When you look at a component, you can see which props are being passed, which makes your apps easy to reason about.

In some cases, you want to pass data through the component tree without having to explicitly pass the props down manually at every level.

This can be done in React using the Context API.

Resources

Official Context Documentation https://reactjs.org/docs/context.html

Usage

Let's suppose you have an app structured similarly to what we have below:

const authToken = 'b9c0bad2c63911e7abc4cec278b6b50a';
const locale = {
  currency: 'USD',
  language: 'en-US',
};

class App extends React.Component {
  render() {
    return (
      <div>
        <ChildComponent locale={locale} authToken={authToken} />
      </div>
    );
  }
}

In this example, we're manually passing down the locale and authToken to our ChildComponent.

As a rule of thumb, you should always try to privilege explicitness over implicitness. However, when it comes to passing down props, especially props that aren't likely to change over time, it can sometimes be quite tedious to have to explicitly pass that information down to deeply nested components within our component tree. In this case, it can sometimes be useful to use context to implicitly pass that information down instead.

To do so, the first thing we need to do is to add a static childContextTypes property to our App class, and a getChildContext() method that will return the values we want to pass down via context:

// As of React v15.5, PropTypes was moved to a separate package
import PropTypes from 'prop-types';

class App extends React.Component {
  static childContextTypes = {
    authToken: PropTypes.string,
    locale: PropTypes.shape({currency: PropTypes.string, language: PropTypes.string}),
  }

  getChildContext() {
    return {
      authToken: 'b9c0bad2-c639-11e7-abc4-cec278b6b50a',
      locale: {
        currency: 'USD',
        language: 'en-US',
      },
    };
  }

  render() {
    return (
      <div>
        <ChildComponent />
      </div>
    );
  }
}

By adding childContextTypes and getChildContext to App (the context provider), React passes the information down automatically and any component in the subtree.

The child components can access it by defining a static contextTypes property.

In this case, if we wanted our ChildComponent to have access to the authToken, we would define a contextTypes property in our component's implementation:

class ChildComponent extends React.Component {
  static contextTypes = {
    authToken: PropTypes.string,
  };

  render() {
    return <p>{this.context.authToken}</p>;
  }
}

If the contextTypes property is not defined, then context will be an empty object.

Last updated