152 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			152 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								---
							 | 
						|||
| 
								 | 
							
								title: Context API
							 | 
						|||
| 
								 | 
							
								---
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								# Context API
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								The Context API has been implemented in the 16.3 version of React.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								It existed before, but was in beta, and thus, unadvised to work with.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								The goal of Context API is to allow developers to have an easy communication between components, without needing them to be closely related (Parent/Children components).
							 | 
						|||
| 
								 | 
							
								This also reduce the need for prop drilling (passing down the props through several components), which allows for a cleaner code, easier to maintain and update.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								This get to 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 a bit 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 remember using three things :
							 | 
						|||
| 
								 | 
							
								- Create a Provider that will manage our data shared (also called a Store)
							 | 
						|||
| 
								 | 
							
								- Create a Consumer that will communicate with the store
							 | 
						|||
| 
								 | 
							
								- Surrounding 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)
							 |