useReducer() Hook In ReactJS - Part Two

Introduction

 
In the previous article, we have reviewed how to use useReducer() hook in ReactJs and what are the benefits of it. Now, in this article, we will be learning about using multiple useReducer() hooks in a component having a similar state followed by using the useContext() hook along with the useReducer() hook.
 

Using multiple useReducer() hook

 
Whenever there is a requirement of using the same state along with multiple variables, we can use useReducer() hook. Let’s see the demo.
 
Create MathMultipleReducer.js component,
  1. import React, { useReducer } from 'react'  
  2.   
  3. const initialState = 0  
  4. const reducer = (state, action) => {  
  5.     switch (action) {  
  6.         case 'addition':  
  7.             return state + 1  
  8.         case 'subtraction':  
  9.             return state - 1  
  10.         case 'reset':  
  11.             return initialState  
  12.         default:  
  13.             return state  
  14.     }  
  15. }  
  16.   
  17. function MathMultipleReducer() {  
  18.     const[countOne,dispatchOne] = useReducer(reducer, initialState)  
  19.     const[countTwo,dispatchTwo] = useReducer(reducer, initialState)  
  20.     return (  
  21.         <div>  
  22.             <div> Counter One - {countOne}</div>  
  23.             <button onClick={() => dispatchOne('addition')}>Addition</button>  
  24.             <button onClick={() => dispatchOne('subtraction')}>Subtraction</button>  
  25.             <button onClick={() => dispatchOne('reset')}>Reset</button>  
  26.             <div> Counter Two - {countTwo}</div>  
  27.             <button onClick={() => dispatchTwo('addition')}>Addition</button>  
  28.             <button onClick={() => dispatchTwo('subtraction')}>Subtraction</button>  
  29.             <button onClick={() => dispatchTwo('reset')}>Reset</button>  
  30.         </div>  
  31.     )  
  32. }  
  33.   
  34. export default MathMultipleReducer   
The output of it will display as below.
 
When clicking on Addition, it will update the first counter.
 
On clicking on Subtract, it will update the second counter.
 
 

useReducer() hook with the useContext() hook

 
SO far we have seen how to use useReducer() hook in ReactJs and how we can use a single state along with multiple variables. We have also seen how to locally manage state. Now using useReducer() along with the useContext() hook allow to Share state or props between components i.e) creating the global component. So, for this, we will be creating 3 components that will share a single state component among 3 of them - UserName.js,UserGender.js, and UserAge.js.
 
Let’s add a code in App.js.
  1. import React, { useReducer } from 'react';  
  2. import './App.css';  
  3. import UserName from './components/UserName';  
  4. import UserGender from './components/UserGender';  
  5. import UserAge from './components/UserAge';  
  6.   
  7. const initialUser = {  
  8.   Name: '',  
  9.   Age: '',  
  10.   Gender: ''  
  11. }  
  12.   
  13. const reducer = (state, action) => {  
  14.   switch (action.type) {  
  15.     case 'UserName':  
  16.       return {  
  17.         Name: action.Name,  
  18.         Gender: '',  
  19.         Age: ''  
  20.       }  
  21.     case 'UserAge':  
  22.       return {  
  23.         ...state,  
  24.         Age: action.Age  
  25.       }  
  26.     case 'UserGender':  
  27.       return {  
  28.         ...state, Gender: action.Gender  
  29.       }  
  30.     default:  
  31.       return state  
  32.   }  
  33. }  
  34.   
  35. export const UserContext = React.createContext()  
  36.   
  37. function App() {  
  38.   const [user, dispatch] = useReducer(reducer, initialUser)  
  39.   
  40.   return (  
  41.     <div className="App">  
  42.       <UserContext.Provider value={{ user, dispatch }}>  
  43.   
  44.         <UserName />  
  45.         {user.Name && <UserGender />}  
  46.         {user.Gender && <UserAge />}  
  47.       </UserContext.Provider>  
  48.       {  
  49.         user.Age && (  
  50.           <p>User name is <b>{user.Name}</b> having gender <b>{user.Gender}</b> of Age <b>{user.Age}</b></p>  
  51.         )  
  52.       }  
  53.     </div>  
  54.   );  
  55. }  
  56.   
  57. export default App;   
UserName.js,
  1. import React, { useState, useContext } from 'react'  
  2. import { UserContext } from '../App'  
  3.   
  4. function UserName() {  
  5.     const { dispatch } = useContext(UserContext)  
  6.   
  7.     const [userName, setName] = useState('')  
  8.   
  9.     return (  
  10.           
  11.         <div>  
  12.             <input type="text" placeholder="Name" value={userName} onChange={(e) => { setName(e.target.value) }} />  
  13.   
  14.             <button type="button" onClick={() => dispatch({ type: 'UserName', Name: userName })}>Next</button>  
  15.         </div>  
  16.     )  
  17.       
  18. }  
  19.   
  20. export default UserName   
UserGender.js,
  1. import React, { useState,useContext } from 'react'  
  2. import { UserContext } from '../App'  
  3.   
  4. function UserGender() {  
  5.     const [gender, setGender] = useState('')  
  6.     const {user, dispatch } = useContext(UserContext)  
  7.     return (  
  8.         <div>  
  9.             <h2>Gender value for user {user.Name}</h2>  
  10.             <input type="text" placeholder="Gender" value={gender} onChange={(e) => { setGender(e.target.value) }} />  
  11.   
  12.             <button type="button" onClick={() => dispatch({ type: 'UserGender', Gender: gender })}>Next</button>  
  13.         </div>  
  14.     )  
  15. }  
  16.   
  17. export default UserGender   
UserAge.js,
  1. import React, { useState,useContext } from 'react'  
  2. import { UserContext } from '../App'  
  3.   
  4. function UserAge() {  
  5.     const [age, setAge] = useState('')  
  6.     const {user, dispatch } = useContext(UserContext)  
  7.     return (  
  8.         <div>  
  9.             <h2>age value for user {user.Name}</h2>  
  10.             <input type="text" placeholder="age" value={age} onChange={(e) => { setAge(e.target.value) }} />  
  11.   
  12.             <button type="button" onClick={() => dispatch({ type: 'UserAge', Age: age })}>Submit</button>  
  13.         </div>  
  14.     )  
  15. }  
  16.   
  17. export default UserAge   
The output will display as below.
 
Add name and click on the "Next" button.
 
Add Gender and click on the "Next" button.
 
After adding all values, it will display output as above.
 

Summary

 
In this article, we have reviewed about using multiple useReducer() in a single component to use the same state for different values and using state and props among components.
 
You can download the source code attached along with this article. In the next article, we will be learning about fetching data from API using useReducer() hook.