# React Context Basics

> An introduction to React Context.

- Canonical: https://dennisokeeffe.com/blog/2018-09-18-react-context-basics
- Published: 2018-09-18
- Updated: 2018-09-18

## 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.

```javascript
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`

```javascript
// 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...

```javascript
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

```javascript
// 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

```javascript
// 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 |                                                               |
