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)
 |