Introduction to 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.

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,

const array1 = [1, 2, 3, 4,5];  
  
const reducer = (accumulator, currentValue) => accumulator + currentValue;  
  
// 1 + 2 + 3 + 4  
  
console.log(array1.reduce(reducer));  
  
// expected output: 10  
  
// 5 + 1 + 2 + 3 + 4  
  
console.log(array1.reduce(reducer, 6));  
  
// 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: 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.

import React, { useReducer } from 'react'  
  
const initialState = 0  
  
const reducer = (state, action) => {  
    switch (action) {  
        case 'addition':  
            return state + 1  
        case 'subtraction':  
            return state - 1  
        case 'multiply':  
            return state * 2  
        case 'divide':  
            return state / 2  
        case 'reset':  
            return initialState  
        default:  
            return state  
    }  
}  
  
function MathComponent() {  
  
    const[count,dispatch] = useReducer(reducer, initialState)  
  
    return (  
        <div>  
            <div> Output is - {count}</div>  
            <button onClick={() => dispatch('addition')}>Addition</button>  
            <button onClick={() => dispatch('subtraction')}>Subtraction</button>  
            <button onClick={() => dispatch('multiply')}>Multiplication</button>  
            <button onClick={() => dispatch('divide')}>Division</button>  
            <button onClick={() => dispatch('reset')}>Reset</button>  
        </div>  
    )  
}  
  
export default MathComponent  

Now, we will be importing MathComponent.js in App.js.

import React from 'react';  
import './App.css';  
import MathComponent from './components/MathComponent';  
  
function App() {  
  return (  
    <div className="App">  
      <MathComponent/>  
    </div>  
  );  
}  
  
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.

import React, { useReducer } from 'react'  
  
const initialState = {  
    value: 0  
}  
  
const reducer = (state, action) => {  
    switch (action.type) {  
        case 'addition':  
            return { value: state.value + 1}  
        case 'subtraction':  
            return { value: state.value - 1}  
        case 'multiply':  
            return { value: state.value * 2}  
        case 'divide':  
            return {value: state.value / 2}  
        case 'reset':  
            return initialState  
        default:  
            return state  
    }  
}  
  
function MathComplex() {  
    const [count, dispatch] = useReducer(reducer, initialState)  
  
    return (  
        <div>  
            <div> Output is - {count.value}</div>  
            <button onClick={() => dispatch({ type: 'addition' })}>Addition</button>  
            <button onClick={() => dispatch({ type: 'subtraction' })}>Subtraction</button>  
            <button onClick={() => dispatch({ type: 'multiply' })}>Multiplication</button>  
            <button onClick={() => dispatch({ type: 'divide' })}>Division</button>  
            <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>  
        </div>  
    )  
}  
  
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.

import React, { useReducer } from 'react'  
  
const initialState = {  
    counter1: 0,  
    counter2:0  
}  
  
const reducer = (state, action) => {  
    switch (action.type) {  
        case 'addition':  
            return {...state, counter1: state.counter1 + action.value }  
        case 'subtraction':  
            return {...state, counter1: state.counter1 - action.value }  
        case 'additionByVal':  
            return {...state, counter2: state.counter2 + action.value }  
        case 'subtractionByVal':  
            return {...state, counter2: state.counter2 - action.value }  
        case 'multiply':  
            return {...state, counter1: state.counter1 * action.value }  
        case 'divide':  
            return {...state, counter1: state.counter1 / action.value }  
        case 'reset':  
            return initialState  
        default:  
            return state  
    }  
}  
  
function MathComplex() {  
    const [count, dispatch] = useReducer(reducer, initialState)  
  
    return (  
        <div>  
            <div> Output is Counter 1 - {count.counter1}</div>  
            <div> Output is Counter 2 - {count.counter2}</div>  
            <button onClick={() => dispatch({ type: 'addition', value: 1 })}>Addition</button>  
            <button onClick={() => dispatch({ type: 'subtraction', value: 1 })}>Subtraction</button>  
            <button onClick={() => dispatch({ type: 'additionByVal', value: 5 })}>Addition By 5</button>  
            <button onClick={() => dispatch({ type: 'subtractionByVal', value: 5 })}>Subtraction By 5</button>  
            <button onClick={() => dispatch({ type: 'multiply', value: 2 })}>Multiplication</button>  
            <button onClick={() => dispatch({ type: 'divide', value: 2 })}>Division</button>  
  
            <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>  
        </div>  
    )  
}  
  
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.

Now in the next article we will go in detail of using useReducer() hook.

Any question or feedback or suggestion, please do comment and let me know.


One comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s