October 16, 2024

“useReducer”: A more powerful State Management

Spread the love

Overview

useReducer is another hook provided by React for managing the state. We generally use useReducer over useState when we have to manage complex state logic that involves multiple sub-values or when the next state depends on the previous one.

General Syntax

const [state, dispatchFn] = useReducer( reducerFn, initialState, initFn )


What does it return?

It returns two values, so we can use array restructuring to store those values (similar to useState)

  • state: latest state snapshot (similar to useState)
  • dispatchFn: function that describes how to can update the state value. You can add additional information (aka payload) to dispatchFn, which can be used by the reducer.

What are the arguments?

  • reducerFn: a funciton that is triggered automatically once as action is dispatched (via dispatchFn()). It acceps 2 parameters: the current state and an action object. Depending on the action object, the reducer function must update the stae in an immutable manner and return the new state.
  • initialState: the initial state value. Similar to useState it can either of any data type, but usually we use objects since useReducer is mainly used to handle complicated and various states simulaneously.
  • initFn: function to se the initial state programatically (optional)

Example

Email input field

The task is to implement an input field that takes an email as an input and also validates it using a simple condition that the entered email should include ‘@’ in it.


Creating a general structure using react functional component

import React from 'react';

const login = () => {
    return (
        <label htmlFor='email'>E-Mail</label>
        <input type='email' value={value} onChange={emailChangeHandler} onBlur={validateEmailHandler}/>
        );
};

In the above example, we can imagine handling two states: email value state and email validity state.
We can use useState and manage both the states separately but let’s use useReducer and manage both the states together.


Defining useReducer

const [ emailState, dispatchEmail ] = useReducer( emailReducer, emailInitialValue )
Some explanation:
emailState: the current state of the email
dispatchEmail: function returned from useReducer for updating the states
emailReducer: function determining how the states are updated
emailInitialValue: initial value of the state set by the user

Now let’s set the emailInitialValue and define emailReducer

const [ emailState, dispatchEmail ] = useReducer( emailReducer, emailInitialValue )

emailInitialValue = {
    value: "",
    isValid: null,
  };

const emailChangeHandler = (event) => {
    dispatchEmail({ type: "USER_INPUT", val: event.target.value });
  };

const validateEmailHandler = () => {
    dispatchEmail({ type: "INPUT_BLUR" });
  };

const emailReducer = (state, action) => {
  if (action.type === "USER_INPUT") {
    return { value: action.val, isValid: action.val.includes("@") };
  }
  if (action.type === "INPUT_BLUR") {
    return { value: state.value, isValid: state.value.includes("@") };
  }
  return { value: "", isValid: false };
};

emailInitialValue:
Since we need to manage two states we will an empty string for the value and null for the validity.

emailChangeHandler:
This is a function triggered whenever there is a change in the input field. Here we call the dispatchEmail function to set the state value to update the type as well as value for the state.

validateEmailHandler:
This function is triggered when the email input field loses focus. Here call the dispatchEmail function to set only the type of the state, not value.

emailReducer:
Here, we can use the actions set for our state and update the value accordingly.
When the action type is “USER_INPUT”, we return the value as action.val (which refers to event.target.value) and update the isValid property based on the condition set.
And, when the action type is “INPUT_BLUR”, we check the state for value and update the validity based on that.


Hopefully, now you know how / when to use useReducer hook in react. If you are interested in understanding how useState works then you can read my post about it here


Spread the love

One thought on ““useReducer”: A more powerful State Management

Leave a Reply

Your email address will not be published. Required fields are marked *