Why we should use useReducer instead of useState in some specific scenarios?

In React, both useState and useReducer are used for managing state, but useReducer is generally preferred when:

  1. The state logic is complex (e.g., involving multiple sub-values or interactions).
  2. State updates depend on previous state in more complex ways.
  3. The state involves multiple values that need to be updated in a coordinated manner.

Example of useState and useReducer when handle user form. With useReducer you can manage the whole object together

useState:

import React, { useState } from 'react';

function FormWithUseState() {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [isValid, setIsValid] = useState(false);

const handleNameChange = (e) => {
setName(e.target.value);
};

const handleEmailChange = (e) => {
setEmail(e.target.value);
};

const handleSubmit = () => {
// Form submit logic
setIsValid(name !== '' && email !== '');
};

return (
<div>
<input type="text" value={name} onChange={handleNameChange} placeholder="Name" />
<input type="email" value={email} onChange={handleEmailChange} placeholder="Email" />
<button onClick={handleSubmit} disabled={!isValid}>Submit</button>
</div>
);
}

useReducer:

import React, { useReducer } from 'react';

const initialState = {
name: '',
email: '',
isValid: false,
};

function formReducer(state, action) {
switch (action.type) {
case 'SET_NAME':
return { ...state, name: action.payload };
case 'SET_EMAIL':
return { ...state, email: action.payload };
case 'SET_VALID':
return { ...state, isValid: action.payload };
default:
return state;
}
}

function FormWithUseReducer() {
const [state, dispatch] = useReducer(formReducer, initialState);

const handleNameChange = (e) => {
dispatch({ type: 'SET_NAME', payload: e.target.value });
};

const handleEmailChange = (e) => {
dispatch({ type: 'SET_EMAIL', payload: e.target.value });
};

const handleSubmit = () => {
dispatch({ type: 'SET_VALID', payload: state.name !== '' && state.email !== '' });
};

return (
<div>
<input
type="text"
value={state.name}
onChange={handleNameChange}
placeholder="Name"
/>
<input
type="email"
value={state.email}
onChange={handleEmailChange}
placeholder="Email"
/>
<button onClick={handleSubmit} disabled={!state.isValid}>Submit</button>
</div>
);
}