Context API – React


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, let’s 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> It’s {value.time} ! </p>} </TimeContext.Consumer> );

This should show:

<p> It’s 17:00 ! </p>

Modify the context dynamically

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

Let’s 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 we’ll 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> It’s {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 that’ll 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

This article needs improvement. You can help improve this article. You can also write similar articles and help the community.