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
You should take part in a contest for one of the best blogs on the web. I will recommend this site!