React Context Basics

An introduction to React Context.

On this page

Basic Introduction

System Description
Props Get data from a parent component to a direct child component
Context Gets data from a parent component to any nested child component

An App with Context

A basic app where we want to pass context of things like language everywhere.

class App extends Component {
  state = { langauge: "english" };

  onLanguageChange = (language) => this.setState({ language });

  render() {
    // return elements with onClick to change state
  }
}

Getting Data Out of Context

  1. Create context file
  2. Set contextType as static property to class
  3. Consume from this.context
  4. Update the context using the Provider
// context/language/index.js
import React from 'react';

// creating context with default 'english'
export default React.createContext('english');

// inside of a component
import LanguageContext from 'path/to/file';
export default class Button extends React.Component {
    static contextType = LanguageContext;

    render() {
        const text = this.context === 'english' ? 'Submit' : 'Voorleggen';
        return <button>{text}</button>
    }
}

To update the context, from a higher provider we could set...

class App extends Component {
    state = {langauge: 'english'};

    onLanguageChange = language => this.setState({language});

    render() {
        // return elements with onClick to change state
        <LanguageContext.Provider value={this.state.language}>
           <ChildThatContainsButton>
        </LanguageContext.Provider>
    }
}

Gotchas Around Context

The big gotcha with the context is dealing with the value prop given to the provider.

Alternative Consumption of Data with Consumers

// context/language/index.js
import React from 'react';

// creating context with default 'english'
export default React.createContext('english');

// inside of a component
import LanguageContext from 'path/to/file';
export default class Button extends React.Component {
    render() {
        return <button>
            <LanguageContext.Consumer>
              {value => value === 'english' ? 'Submit' : 'Voorleggen'}
           </LanguageContext.Consumer>
        </button>
    }
}

Using Multiple Consumers

// context/language/index.js
import React from 'react';

// creating context with default 'english'
export default React.createContext('english');

// inside of a component
import LanguageContext from 'path/to/file';
export default class Button extends React.Component {
    render() {
        return <button>
            <ColorContext.Consumer>
            {color => {
                <LanguageContext.Consumer>
                    {value => value === 'english' ? 'Submit' : 'Voorleggen'}
                </LanguageContext.Consumer>
            }}
           </ColorContext.Consumer>
        </button>
    }
}

Context vs Redux

Redux Context
Excellent documentation No need for extra lib
Well-known for design patterns Hard to build a 'store' component with cross cutting concerns
Tremendous amount of open source libs