useReducer Function – React
useReducer function in React, which is not related to redux (although it has a similar logic), is used for a state management, especially if we have multiple states connected to each other or a complex state to manage and update.
the structure of useReducer function is as follows:
const [state, dispatchFunction] = useReducer (reducerFunction, initialState, initialFunction(for complex states, not used generally))
- “state” value in return array is the latest state
- “dispatchFunction” dispatches an action, which will be consumed by reducerFunction and the state is updated accordingly.
the structure of reducerFunction as follows:
reducerFunction = (prevState, action) => newState
It takes previous state and the action dispatched by dispatchFunction, and the newState is returned by this function.
Although using useReducer is not a must, there are some cases which can be judged it is better to use. I will give such an example.
In the example, two states connected to each other will be managed by useReducer() function. Keep in my mind that you can use two different useState() functions.
In the example below, two different actions are dispatched by input blur and input change events. For every keystroke on e-mail input, INPUT_CHANGE action is dispatched, which changes both e-mail value and isValid fields, whereas INPUT_BLUR action only updates isValid field, while keeping value the same.
import React, { useReducer } from "react";
import classes from "./Login.module.css";
const emailReducer = (state, action) => {
const validRegex =
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|.(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{3,}))$/;
if (action.type === "INPUT_CHANGE") {
return {
value: action.val,
isValid: action.value.match(validRegex) ? true : false,
};
}
if (action.type === "INPUT_BLUR") {
return {
value: state.value,
isValid: action.value.match(validRegex) ? true : false,
};
}
return {
value: state.value,
isValid: state.isValid,
};
};
const Login = (props) => {
const [emailState, dispatchEmail] = useReducer(emailReducer, {
value: "",
isValid: false,
});
const inputBlurHandler = (event) => {
dispatchEmail({ type: "INPUT_BLUR", value: event.target.value });
};
const inputChangeHandler = (event) => {
dispatchEmail({ type: "INPUT_CHANGE", value: event.target.value });
};
return (
<div className={classes.form}>
<div className={classes.label}>e-mail</div>
<div className={classes.inputGroup}>
<input
onBlur={inputBlurHandler}
onChange={inputChangeHandler}
className={classes.input}
/>
<div className={emailState.isValid ? classes.label : classes.invalid}>
{emailState.isValid
? "valid e-mail"
: "please enter a valid e-mail address"}
</div>
</div>
<div className={classes.label}>name</div>
<input className={classes.input} />
<button>OK</button>
</div>
);
};
export default Login;