150 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
---
 | 
						||
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, let’s say we want to share some time between components.
 | 
						||
 | 
						||
```javascript
 | 
						||
// 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 (<ShowTime /> in this case).
 | 
						||
 | 
						||
```javascript
 | 
						||
// 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:
 | 
						||
 | 
						||
```javascript
 | 
						||
// 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:
 | 
						||
```javascript
 | 
						||
<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.
 | 
						||
```javascript
 | 
						||
// 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:
 | 
						||
 | 
						||
```javascript
 | 
						||
// 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
 | 
						||
 | 
						||
- [React - Context Official Documentation ](https://reactjs.org/docs/context.html)
 |