useReducer() Hook In ReactJS - Part One

Introduction

 
In the previous article, we have learned about the useContext() hook and how it is used in React. Now in this article, we will understand another hook named useReducer() hook, how it is used, and the purpose of using it.
 

What is Reducer?

 
Before starting about useReducer() hook, we first should know about Reduce in JavaScript.
 
The reduce() method in JavaScript executes a reducer function on each element of the array and provides a single value as output.
  1. Syntax- Array.reduce(<reducer func>,[initialValue])  
This function takes 2 parameters - first is reducer function which itself takes 2 arguments.
 
So, let’s check an example.
  1. const array1 = [1, 2, 3, 4,5];  
  2.   
  3. const reducer = (accumulator, currentValue) => accumulator + currentValue;  
  4.   
  5. // 1 + 2 + 3 + 4  
  6.   
  7. console.log(array1.reduce(reducer));  
  8.   
  9. // expected output: 10  
  10.   
  11. // 5 + 1 + 2 + 3 + 4  
  12.   
  13. console.log(array1.reduce(reducer, 6));  
  14.   
  15. // expected output: 15  
As per the example, the reducer function first takes an accumulative value and current value and passes these to array.reduce() method as an argument.
 
Now, we understand reducer and reduce function so let us move ahead for the useReducer() hook.
 

useReducer() hook

 
This hook is used for state management. This stands as an alternative for useState() hook. This is a hook that includes in React 16.7.0. It accepts a reducer function along with initial application state and returns the current application state.
 
Syntax
  1. useReducer(reducer,initialState)  
reducer – here reducer is a callback function.
initialState – It is the initial value.
 
So, for better understanding of useReducer() hook, let’s see an example. Here, we will be creating a MathComponent.js that will include arithmetic operators to perform an operation.
  1. import React, { useReducer } from 'react'  
  2.   
  3. const initialState = 0  
  4.   
  5. const reducer = (state, action) => {  
  6.     switch (action) {  
  7.         case 'addition':  
  8.             return state + 1  
  9.         case 'subtraction':  
  10.             return state - 1  
  11.         case 'multiply':  
  12.             return state * 2  
  13.         case 'divide':  
  14.             return state / 2  
  15.         case 'reset':  
  16.             return initialState  
  17.         default:  
  18.             return state  
  19.     }  
  20. }  
  21.   
  22. function MathComponent() {  
  23.   
  24.     const[count,dispatch] = useReducer(reducer, initialState)  
  25.   
  26.     return (  
  27.         <div>  
  28.             <div> Output is - {count}</div>  
  29.             <button onClick={() => dispatch('addition')}>Addition</button>  
  30.             <button onClick={() => dispatch('subtraction')}>Subtraction</button>  
  31.             <button onClick={() => dispatch('multiply')}>Multiplication</button>  
  32.             <button onClick={() => dispatch('divide')}>Division</button>  
  33.             <button onClick={() => dispatch('reset')}>Reset</button>  
  34.         </div>  
  35.     )  
  36. }  
  37.   
  38. export default MathComponent  
Now, we will be importing MathComponent.js in App.js.
  1. import React from 'react';  
  2. import './App.css';  
  3. import MathComponent from './components/MathComponent';  
  4.   
  5. function App() {  
  6.   return (  
  7.     <div className="App">  
  8.       <MathComponent/>  
  9.     </div>  
  10.   );  
  11. }  
  12.   
  13. export default App;   
The output will be as below.
 
Initially, it will display the initial value as 0.
 
useReducer() Hook In ReactJS
Now, clicking on the Addition button will add value by 1 as many times as clicked.
 
useReducer() Hook In ReactJS
Clicking on Subtract will reduce value by 1.
 
useReducer() Hook In ReactJS
On clicking of multiplication, the current state value will be multiplied by 2.
 
useReducer() Hook In ReactJS
Now, on clicking Division, it will divide the value by two.
 
useReducer() Hook In ReactJS
When we click Reset, it will set to 0 again. 
 
useReducer() Hook In ReactJS
Let’s see the process.
 
First, the useReducer() method accepts reducer and initialState as a parameter.
 
useReducer() Hook In ReactJS
 
As in the above image, the reducer method will take the current state and action that are needed to be performed in that method.
 
After calling useReducer, it will return the current state and dispatch method which act as a parameter as shown in the example.
 
Now, let’s move one step ahead.
 
Create another component named MathComplex.js and in place of a single variable in reduce method, we will be passing an object for both, state and action.
  1. import React, { useReducer } from 'react'  
  2.   
  3. const initialState = {  
  4.     value: 0  
  5. }  
  6.   
  7. const reducer = (state, action) => {  
  8.     switch (action.type) {  
  9.         case 'addition':  
  10.             return { value: state.value + 1}  
  11.         case 'subtraction':  
  12.             return { value: state.value - 1}  
  13.         case 'multiply':  
  14.             return { value: state.value * 2}  
  15.         case 'divide':  
  16.             return {value: state.value / 2}  
  17.         case 'reset':  
  18.             return initialState  
  19.         default:  
  20.             return state  
  21.     }  
  22. }  
  23.   
  24. function MathComplex() {  
  25.     const [count, dispatch] = useReducer(reducer, initialState)  
  26.   
  27.     return (  
  28.         <div>  
  29.             <div> Output is - {count.value}</div>  
  30.             <button onClick={() => dispatch({ type: 'addition' })}>Addition</button>  
  31.             <button onClick={() => dispatch({ type: 'subtraction' })}>Subtraction</button>  
  32.             <button onClick={() => dispatch({ type: 'multiply' })}>Multiplication</button>  
  33.             <button onClick={() => dispatch({ type: 'divide' })}>Division</button>  
  34.             <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>  
  35.         </div>  
  36.     )  
  37. }  
  38.   
  39. export default MathComplex  
The above example has an object for action which includes the type that will be rendered by the reduce method.
 
The output will be displayed the same as above.
 
Now, add 1 more counter variable and 2 other buttons that will perform the operations based on values passed from dispatch function.
  1. import React, { useReducer } from 'react'  
  2.   
  3. const initialState = {  
  4.     counter1: 0,  
  5.     counter2:0  
  6. }  
  7.   
  8. const reducer = (state, action) => {  
  9.     switch (action.type) {  
  10.         case 'addition':  
  11.             return {...state, counter1: state.counter1 + action.value }  
  12.         case 'subtraction':  
  13.             return {...state, counter1: state.counter1 - action.value }  
  14.         case 'additionByVal':  
  15.             return {...state, counter2: state.counter2 + action.value }  
  16.         case 'subtractionByVal':  
  17.             return {...state, counter2: state.counter2 - action.value }  
  18.         case 'multiply':  
  19.             return {...state, counter1: state.counter1 * action.value }  
  20.         case 'divide':  
  21.             return {...state, counter1: state.counter1 / action.value }  
  22.         case 'reset':  
  23.             return initialState  
  24.         default:  
  25.             return state  
  26.     }  
  27. }  
  28.   
  29. function MathComplex() {  
  30.     const [count, dispatch] = useReducer(reducer, initialState)  
  31.   
  32.     return (  
  33.         <div>  
  34.             <div> Output is Counter 1 - {count.counter1}</div>  
  35.             <div> Output is Counter 2 - {count.counter2}</div>  
  36.             <button onClick={() => dispatch({ type: 'addition', value: 1 })}>Addition</button>  
  37.             <button onClick={() => dispatch({ type: 'subtraction', value: 1 })}>Subtraction</button>  
  38.             <button onClick={() => dispatch({ type: 'additionByVal', value: 5 })}>Addition By 5</button>  
  39.             <button onClick={() => dispatch({ type: 'subtractionByVal', value: 5 })}>Subtraction By 5</button>  
  40.             <button onClick={() => dispatch({ type: 'multiply', value: 2 })}>Multiplication</button>  
  41.             <button onClick={() => dispatch({ type: 'divide', value: 2 })}>Division</button>  
  42.   
  43.             <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>  
  44.         </div>  
  45.     )  
  46. }  
  47.   
  48. export default MathComplex  
The output will be displayed as below.
 
Clicking on Add will add value to counter 1.
 
useReducer() Hook In ReactJS
 Clicking on Addition By 5 will update the value to counter 2.
 
useReducer() Hook In ReactJS
As you can notice in code, the spread operator is used to just denote the update of a single counter variable and append rest of the counter values with it.
 
So, the benefit of using this approach is that we can use as many variables as we want and, we can keep values in variables need for incrementing/decrementing values without any hardcoding.
 

Summary

 
In this article, we have learned about useReducer() hook and how it can be used in React and in how many ways it can be used. You can download the attached source code along with this article. Now in the next article we will go in detail of using useReducer() hook.