Tutorial

Understanding the React Context API

Published on April 24, 2018
author

Alligator.io

Understanding the React Context API

With React 16.3 we now have access to a brand new context API. With React’s old context API, the official recommendation was for developers to avoid using it, but now the new context API is a first-class citizen.

While not meant as a replacement for state management libraries like Redux or MobX, the context API allows for an easy way to share global data between multiple components without having to pass it as props. It solves a common problem known as the prop-drilling problem where props would need to be passed down to multiple components in the tree to reach the component that needs it.

The new API is especially useful to provide data that’s needed by a high percentage of the components in the tree. Global preferences like the selected theme or selected locale option are two good examples.

In this post we’ll explain how to use the new context API in as few words as possible. We’ll create a simple Locale context that provides the language preference between English and French to components in the app. Note that it’s just meant as a simple example to demonstrate an app’s global preference, and for real i18n in React a more robust solution like i18next is more appropriate.

React.createContext

To create a new context, use React’s new createContext function:

export const LocaleContext = React.createContext('en');

Here we also pass-in a default value of ‘en’ to the context, but you can also omit this default value if you’d like.

The createContext function returns a Provider and a Consumer component.

Provider

The Provider component is used to wrap components in the tree that will need access to the value from the context. Here let’s create a LocaleProvider component that wraps our LocaleContext’s provider and offers a way to change the context’s locale value:

context/LocaleContext.js
import React from 'react';

export const LocaleContext = React.createContext();

class LocaleProvider extends React.Component {
  constructor(props) {
    super(props);

    this.changeLocale = () => {
      this.setState(state => {
        const newLocale = state.locale === 'en' ? 'fr' : 'en';
        return {
          locale: newLocale
        };
      });
    };

    this.state = {
      locale: 'en',
      changeLocale: this.changeLocale
    };
  }

  render() {
    return (
      <LocaleContext.Provider value={this.state}>
        {this.props.children}
      </LocaleContext.Provider>
    );
  }
}

export default LocaleProvider;

Notice how the LocaleProvider component is just a thin wrapper around our context’s Provider component. The value of the context is passed to the provider using the value prop and then we just render LocaleContext’s children.

We pass our component’s state as the context value and from there the locale value and the changeLocale method to change the value will be available.

Using the Provider

We can make use of our provider at the top level of our App component:

App.js
import React, { Component } from 'react';

import LocaleProvider from './context/LocaleContext';
import Greeting from './Greeting';
import ToggleLocale from './ToggleLocale';

class App extends Component {
  render() {
    return (
      <LocaleProvider>
        <Greeting />
        <ToggleLocale />
      </LocaleProvider>
    );
  }
}

export default App;

Consumer

Now all that’s left to do is access the values from the context using the Consumer component.

Our Greeting component looks like this:

Greeting.js
import React from 'react';

import { LocaleContext } from './context/LocaleContext';

export default () => {
  return (
    <LocaleContext.Consumer>
      {localeVal =>
        localeVal.locale === 'en' ? <h1>Welcome!</h1> : <h1>Bienvenue!</h1>
      }
    </LocaleContext.Consumer>
  );
};

And our ToggleLocale component looks like this:

ToggleLocale.js
import React from 'react';

import { LocaleContext } from './context/LocaleContext';

export default () => {
  return (
    <LocaleContext.Consumer>
      {localeVal => (
        <button onClick={localeVal.changeLocale}>Change language</button>
      )}
    </LocaleContext.Consumer>
  );
};

The Consumer component uses the render prop pattern and expects a function as its children prop that will receive the value from the context. We can then access the context’s values and call the methods that it makes available.

With this in place, we can toggle the app’s greeting message between Welcome and Bienvenue.


In our example, the Greeting and ToggleLocale components are direct children of the LocaleProvider component, but they could be at any depth down the component tree and they would still have access to the global context data as long as the context’s consumer component is used and that the provider is somewhere higher up the tree.

⚛️ With this you should be good to start using the new context API in your apps. For more information, you can also refer to the official docs.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Alligator.io

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.