React Context API: Introduction and practical guide

As with most component-based frontend frameworks, passing some form of data from one component to another is in high demand. This leads to components having data they don’t actually need, but they need to pass on down the tree. The React Context API aims to solve this problem. Moreover, it provides a way to share data values between components without having to pass a prop through every level of the app tree.

Prerequisite

Before we dive into the context API, to ensure you can easily follow along it’s important you have the following:

  • Familiarity and some experience with React.
  • Knowledge of setting up an application with create-react-app.
  • Working with NPM modules.

What is the React Context API?

react context api

The React Context API is a component structure provided by the React framework, which enables us to share specific forms of data across all levels of the application. It’s aimed at solving the problem of prop drilling.

Before the Context API, we could use a module to solve this. It led to the increasing popularity of state management libraries like Redux. Libraries like Redux allows you to get data from the store easily, anywhere in the tree.

Related:
Magic links: Effective authentication strategy for React applications

The Context API has actually always been there but was considered experimental. Moving forward the API was improved to stability. And as of the release of version 16.3, the feature was made and subsequently considered as a new addition to the clan of features.

Before now many of the tools we have been used to like react-reduxreact-native-fluxMobX-react, and react-router all used context to function, so you were probably already using and loving it, even if not directly. So let’s learn how best to use it.

When to use the Context API


The React Context API is useful for sharing data that can be considered global, such as the currently authenticated user, the theme settings for the application ,etc. In situations where we have these types of data, we can use the React Context API. We don’t necessarily have to use extra modules.

In fact, any situation where you have to pass a prop through a component reaching another component is where you can use the Context API.

How to use the Context API

With the new Context API, several new functions have been added to the mix creating giving us a rich tool to work with. If you’ve previously attempted to use the old (experimental, do not use) Context API, you may have come across some methods. However, let’s look at some code snippets on how we can use the React Context API.

In this example, we will create a simple instance using the Context API.

You can use create-react-app to create a sample project to work with:

    $ npx create-react-app sample

In the src directory, you can now play along with the tutorial. Let’s start by modifying or adding a few files.

Create a language.js file with the following content:

    const lang = {
            esp:{
                    open: 'abierto',
                    close: 'cerca',
                    changeLanguage: 'haga clic para cambiar su idioma al inglés',
                    header: 'Mira tu idioma',
                    text: 'Haga clic en el botón de abajo para cambiar su idioma'
            },
            en: {
                    open: 'open',
                    close: 'close',
                    changeLanguage: 'click to switch to spanish',
                    header: 'Watch your language',
                    text: 'click on the button below to change your language'
            }
    }

    export default lang;

Create a context.js file in the src directory with the following content:

    import React from 'react'
    import lan from './language'

    const LanguageContext = React.createContext({
        lang: lan.esp,
        toggleLanguage: () => { }
    });

    export default LanguageContext;

Replace the App.js with the following content:

    import React, { Component } from 'react';
    import './App.css';
    import LanguageContext from './context'
    import lan from './language'

    class App extends React.Component {
      render() {
        return (
          <LanguageContext.Provider value={{lang: lan.en}}>
            <Toolbar />
          </LanguageContext.Provider>
        );
      }
    }

    function Toolbar(props) {
      return (
        <div>
          <CloseButton />
        </div>
      );
    }

    function CloseButton(props) {
      return (
        <LanguageContext.Consumer>
          {context => <Button {...props} text={context.lang.close} />}
        </LanguageContext.Consumer>
      );
    }

    function Button(props) {
      return (
        <button>{props.text}</button>
      );
    }

Let’s have a good look at this, first, we set up a context instance using the createContext function in the React object. This function takes in the default values of the context we wish to create. It’s the starting point of the Context API with this you create the provider and consumer pair.

    const {Provider, Consumer} = React.createContext(default);

To use this object returned, we set up the provider component in the parent component. You can also pass in your prop/data to change the default values.

This component wraps the intended parent component. In addition, its values are made available to the child component via the corresponding consumer component.

    import lan from './language'

    <LanguageContext.Provider value={{lang: lan['en']}}>
        <Toolbar />
    </LanguageContext.Provider>

In this example, the provider wraps the toolbar component in the App component declaration. Therefore allowing the data to be available for use.

    function CloseButton(props) {
      return (
        <LanguageContext.Consumer>
          {context => <Button {...props} text={context.lang.close} />}
        </LanguageContext.Consumer>
      );
    }

Now we can assess the values of the context in any child element using the LanguageContext.Consumer wrapper followed by the arrow function representation to retrieve the data.

Manipulating data within the React Context API

Sometimes we want to change some data in the context. For example: changing the theme of the app when a user changes their theme. To do this, we simply connect the data in the context Provider to the state of the parent element. Then, we change this parent’s state using functions in props. A better way is to have the function that will change the context value passed down in the context itself.

Let’s demonstrate how this will work. In your create-react-app project, make sure the content of the context.js is the same as the following:

    import React from 'react'
    import lan from './language'

    const LanguageContext = React.createContext({
        lang: lan.esp,
        toggleLanguage: () => { }
    });

    export default LanguageContext;

Next, create a LanguageTogglerButton.js file. This will be a button that toggles the theme. Paste the following in the file:

    import React from 'react';
    import LanguageContext from './context';

    function LanguageTogglerButton() {
        return (
            <LanguageContext.Consumer>
                {({ lang, toggleLanguage }) => (
                    <React.Fragment>
                        <header className="App-header">
                            <h1 className="App-title">{lang.header}</h1>
                            <p>{lang.text}</p>
                        </header>
                        <Toolbar />
                    </React.Fragment>
                )}
            </LanguageContext.Consumer>
        );
    }

    function Toolbar(props) {
        return (
            <div>
                <CloseButton />
            </div>
        );
    }

    function CloseButton(props) {
        return (
            <LanguageContext.Consumer>
                {({ lang, toggleLanguage }) => (
                    <Button
                        onClick={toggleLanguage}
                        text={lang.changeLanguage}>
                    </Button>
                )}
            </LanguageContext.Consumer>
        );
    }

    function Button(props) {
        return (
            <button className="App-button" onClick={props.onClick}>{props.text}</button>
        );
    }

    export default LanguageTogglerButton;

Lastly, in App.js you can use like this:

    import React from 'react';
    import './App.css';
    import LanguageContext from './context';
    import LanguageTogglerButton from './LanguageTogglerButton';
    import lang from './language';

    class App extends React.Component {
        constructor(props) {
            super(props);
            this.toggleLanguage = () => {
                this.setState(state => ({
                    lang:
                        state.lang === lang['en']
                            ? lang['esp']
                            : lang['en'],
                }));
            };
            this.state = {
                lang: lang['esp'],
                toggleLanguage: this.toggleLanguage
            };
        }

        render() {
            return (
                <div>
                    <LanguageContext.Provider value={this.state}>
                        <LanguageTogglerButton />
                    </LanguageContext.Provider>
                </div>
            );
        }
    }

    export default App;

In this process, we are able to change the context via a nested component by sending the function. It leads to change the component as part of the state.

Conclusion

The React Context API makes it easier to have our global. It also makes app-wide data available to all components. The Context API has been considered as one of the key features of the react framework. Moreover, it is prominent improvement in the recent releases of the framework.

There are sure to be more improvements and new features from the framework and its development community. In the meantime, enjoy what wonderful features it has like the Context API.

Want to work with web development company?

A development company is the best option if you’re planning a mid-sized or large project but don’t have your own team. To clarify, the biggest advantage of a software development company is that they can take ownership of the whole project.

If you’re considering working with a web development team, you can explore more about us – ArrowHiTech. We are proud to be one of the most well-established outsourcing companies all around the world. In addition, with over 12 years of experience, we can provide the best React JS development services for your business. Also, if you want to go through our showcase, you should visit our product page here: MageSolution or our portfolio: ArrowHiTech portfolio.

magic links
ArrowHiTech services

If you have any questions, don’t hesitate to contact us via:

  • Email: support@arrowhitech.com
  • Phone number: +84 243 7955 813.

Tags

Share