useReducer

useReducer() is similar to useState(). More generic and flexible, it accepts as the first argument an update function called a reducer, which in turn accepts the arguments (state, action) and returns the new state.

useReducer() is usually preferable to useState() when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one. useReducer() also lets you optimize performance for components that trigger deep updates because you can pass dispatch down instead of callbacks.