Den Dribbles

React Context Basics

September 18, 2018

Basic Introduction

SystemDescription
PropsGet data from a parent component to a direct child component
ContextGets data from a parent omponent 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

ReduxContext
Excellent documentationNo need for extra lib
Well-known for design patternsHard to build a ‘store’ component with cross cutting concerns
Tremendous amount of open source libs

A personal blog on all things of interest. Written by Dennis O'Keeffe, Follow me on Twitter