freeCodeCamp/guide/english/react/context-api/index.md

3.9 KiB
Raw Blame History

title
Context API

Context API

The Context API has been implemented in the 16.3 version of React, in previous versions it was still a beta feature.

The goal of the Context API is to allow developers to communicate easily between components, without needing them to be closely related (Parent/Children components). This also reduces the need for prop drilling (passing down the props through several components), which in turn makes for cleaner code that is easier to maintain and update.

This shows its full potential when we want to share data that will be accessed by multiple components.

This is based around two things : a Provider and a Consumer.

Provider

On a file created exclusively to provide data, TimeProvider.js, lets say we want to share some time between components.

// Import createContext
import React, { createContext, Component } from 'react';

// Initialize a context with a time value to it
export const TimeContext = createContext({
  time: '',
});

// Create the TimeProvider class to be used by index.js as a provider and initialize a default value
class TimeProvider extends Component {
  state = {
    time: '17:00',
  };

  // Passing the state that we just set as value to be used by our consumer and returning its children
  render() {
    return (
      <TimeContext.Provider value={this.state}>
        {this.props.children}
      </TimeContext.Provider>
    );
  }
}

export default TimeProvider;

We need to tweak the component that will call the child which needs to consume our context ( in this case).

// index.js
import React from "react";
import ReactDOM from "react-dom";
import { ShowTime} from "./ShowTime";

// Importing our provider
import TimeProvider from "./utils/timeProvider";

// Calling our Hello component inside our provider
function App() {
  return (
      <TimeProvider>
        <ShowTime />
      </TimeProvider>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Consumer

In the ShowTime.js file, let's call the time value using the consumer:

// on ShowTime.js
import React from react;

import { TimeContext } from ./utils/TimeProvider;

export default () => (
  <TimeContext.Consumer>
    {value => <p> Its {value.time} ! </p>}
  </TimeContext.Consumer>
);

This should show:

<p> Its 17:00 ! </p>

Modify the context dynamically

In order to change the time that well provide to the ShowTime component, we need to give our context a function, that can be used by the consumer to update a value.

Lets just add it to our Provider.

// utils.TimeProvider.js
...
// This time we initialize a function to set the time
export const TimeContext = createContext({
  time: "",
  setTime: () => {}
});

// We define the setTime function to store the time well give it
class TimeProvider extends Component {
  state = {
    time : "17:00",
    setTime: time => this.setState({ time : time })
  };

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

export default TimeProvider;

And back on our Consumer:

// on ShowTime.js
import React from react;

import { TimeContext } from ./utils/TimeProvider;

export default () => (
  <TimeContext.Consumer>
    {value => <p> Its {value.time} ! </p>}
    <input type="text" value={time} onChange={e => setTime(e.target.value)} />
  </TimeContext.Consumer>
);

This will give us an input to modify the time thatll be displayed.

We need to implement three things:

  • Create a Provider that will manage our data shared (also called a Store)
  • Create a Consumer that will communicate with the store
  • Surround our Consumer Component with the Provider created so it can use its data

More Information