useContext() Hook In ReactJS

This article talks about the concept of useContext() hook in ReactJs

Introduction

 
In the previous article, we have learned about useEffect() hook and how to fetch data using API using useEffect(). In this article, we will be learning about the useContext() hook.
 

What is React Context

 
In React, suppose we have parent component  having 3 levels of child components,
 
useContext() Hook In ReactJS
Like the above image, if we want to pass any data from parent component to child component C, so as per React we need to pass props to each level to be available to Child component c. This solution may be feasible when a number of child components are many. So, React hooks provides a concept call Context.
 
React Context API allows you to easily access data at different levels of the component tree, without passing prop to every level as we have seen in the previous series by creating context, now in this, it will be achieved using useContext() hook.
 

useContext() hook

 
This hook is used to pass data from one component to another without being specified to each of the component trees.
 
Let’s look at the demo,
 
Create a hierarchy as per above image,
 
Create 4 functional components,
 
ChildC.js
  1. import React from 'react'  
  2.   
  3. function ChildC() {  
  4.     return (  
  5.         <div>  
  6.             Child Component at level 3  
  7.         </div>  
  8.     )  
  9. }  
  10.   
  11. export default ChildC  
ChildB.js
  1. import React from 'react'  
  2. import ChildC from './ChildC'  
  3.   
  4. function ChildB() {  
  5.     return (  
  6.         <div>  
  7.             <ChildC/>  
  8.             Child Component at level 2  
  9.         </div>  
  10.     )  
  11. }  
  12.   
  13. export default ChildB  
ChildA.js
  1. import React from 'react'  
  2. import ChildB from './ChildB'  
  3.   
  4. function ChildA() {  
  5.     return (  
  6.         <div>  
  7.             <ChildB/>  
  8.         Child Component at level 1  
  9.         </div>  
  10.     )  
  11. }  
  12.   
  13. export default ChildA   
ParentComponent.js
  1. import React from 'react'  
  2. import ChildA from './ChildA'  
  3.   
  4. function ParentComponent() {  
  5.     return (  
  6.         <div>  
  7.             <ChildA/>              
  8.         </div>  
  9.     )  
  10. }  
  11.   
  12. export default ParentComponent  
and import in App.js
  1. import React from 'react';  
  2. import './App.css';  
  3. import ParentComponent from './components/ParentComponent';  
  4.   
  5. function App() {  
  6.   return (  
  7.     <div className="App">  
  8.       <ParentComponent/>  
  9.     </div>  
  10.   );  
  11. }  
  12.   
  13. export default App;  
Now to create we have 3 steps,
 
First, create context in App.js
 
Provide value using <UserContext.Provider>
 
Use value of context using <UserContext.Consumer>
 
Create context object and pass value in App.js as below,
  1. import React from 'react';  
  2. import './App.css';  
  3. import ParentComponent from './components/ParentComponent';  
  4.   
  5. export const UserContext = React.createContext()  
  6.   
  7. function App() {  
  8.   return (  
  9.     <div className="App">  
  10.       <UserContext.Provider value={'ReactApp'} >  
  11.       <ParentComponent/>  
  12.       </UserContext.Provider>  
  13.     </div>  
  14.   );  
  15. }  
  16.   
  17. export default App;  
and consume value in ChildC.js
  1. import React from 'react'  
  2. import {UserContext} from '../App'  
  3.   
  4. function ChildC() {  
  5.     return (  
  6.         <div>  
  7.             Child Component at level 3  
  8.             <UserContext.Consumer>  
  9.                 {  
  10.                     user => {  
  11.                         return <div>Context value is {user}</div>  
  12.                     }  
  13.                 }  
  14.             </UserContext.Consumer>  
  15.         </div>  
  16.     )  
  17. }  
  18.   
  19. export default ChildC  
The output it will display as below,
 
useContext() Hook In ReactJS
Now let’s see how multiple values can be consume using context,
  1. import React from 'react';  
  2. import './App.css';  
  3. import ParentComponent from './components/ParentComponent';  
  4.   
  5. export const UserContext = React.createContext()  
  6. export const CategoryContext = React.createContext()  
  7.   
  8. function App() {  
  9.   return (  
  10.     <div className="App">  
  11.       <UserContext.Provider value={'ReactApp'} >  
  12.         <CategoryContext.Provider value={'Programming'}>  
  13.           <ParentComponent />  
  14.         </CategoryContext.Provider>  
  15.       </UserContext.Provider>  
  16.     </div>  
  17.   );  
  18. }  
  19.   
  20. export default App;   
Now import CategoryContext in ChildB.js
  1. import React from 'react'  
  2. import ChildC from './ChildC'  
  3. import {CategoryContext} from '../App'  
  4.   
  5. function ChildB() {  
  6.     return (  
  7.         <div>  
  8.             <ChildC/>  
  9.             Child Component at level 2  
  10.             <CategoryContext.Consumer>  
  11.                 {  
  12.                     category => {  
  13.                        return <div><b>Category is {category}</b></div>  
  14.                     }  
  15.                 }  
  16.             </CategoryContext.Consumer>  
  17.               
  18.         </div>  
  19.     )  
  20. }  
  21.   
  22. export default ChildB   
The output will be displayed as below.
 
useContext() Hook In ReactJS
Now we will import the CategoryContext in ChildC.js to see how nested consumer works,
  1. import React from 'react'  
  2. import {UserContext,CategoryContext} from '../App'  
  3.   
  4. function ChildC() {  
  5.     return (  
  6.         <div>  
  7.             Child Component at level 3  
  8.             <UserContext.Consumer>  
  9.                 {  
  10.                     user => {  
  11.                         return(  
  12.                             <CategoryContext.Consumer>  
  13.                                 {  
  14.                                     category=>{  
  15.                                         return <div><b>Context value is {user} and Category value is {category}</b></div>  
  16.                                     }  
  17.                                 }  
  18.                             </CategoryContext.Consumer>  
  19.   
  20.                         )   
  21.                     }  
  22.                 }  
  23.             </UserContext.Consumer>  
  24.         </div>  
  25.     )  
  26. }  
  27.   
  28. export default ChildC   
Now it will display output as below,
 
useContext() Hook In ReactJS
As in the above example, we have seen how to consume the context we need to approach multi-level nesting, but it is very difficult to read and understand so to make it more readable here we will make use of useContext() hook,
 
Let’s see a demo to useContext() to use context value in a more readable and understandable format,
 
The process of passing creating context and passing value remain the same, we just need to make changes while consuming values.
 
Update code in ChildB.js to consume context value,
  1. import React,{useContext} from 'react'  
  2. import ChildC from './ChildC'  
  3. import {UserContext,CategoryContext} from '../App'  
  4.   
  5. function ChildB() {  
  6.     const user = useContext(UserContext)  
  7.     const category = useContext(CategoryContext)  
  8.     return (  
  9.         <div>  
  10.             <ChildC/>  
  11.             Child Component at level 2  
  12.             <div><i>User is {user}, Category is {category}</i></div>  
  13.               
  14.         </div>  
  15.     )  
  16. }  
  17.   
  18. export default ChildB   
As we can see in above code, we just need to import useContext and after assigning the User.

Context and CategoryContext value to constant variables and we can simply use it as seen above.
 
The output is displayed in italics as below,
 
useContext() Hook In ReactJS
Using useContext() hook makes code more readable and simpler to use.
 

Summary

 
In this article, we have learned about useContext() hook and how it works in React. Now in the next article we will learn about useReducer() hook.