useReducer hook is the alternative to useState and meant to manage state. The principle for useReducer() hook is similar to Redux , but state is not an object, but a pure value & action value is not an object with type property, but pure string. With useReducer() instead of having multiple setState() in different functions, we can have them all in one place. General usage
import React, { useReducer } from 'react'
const initState = 0
function reducer(state, action) {
// return new state
if (action === 'increment') return state + 1
if (action === 'decrement') return state - 1
if (action === 'reset') return initState
// default state
return state
}
function Component() {
const [countState, dispatch] = useReducer(reducer, initState);
return (
<>
<div>Count: {countState}</div>
<button onClick={() => dispatch('increment')}>Increment</button>&emsp
<button onClick={() => dispatch('decrement')}>Decrement</button>&emsp
<button onClick={() => dispatch('reset')}>Reset</button>
</>
);
}
<Component />
One useReducer() for multiple components
<Component />
<Component />
useReducer() with state & action as objects Same approach, but state and actions are enhanced.
const initState3 = { counter: 0, sex: 'male' }
function reducer3(state, action) {
if (action.type === 'increment') { return { ...state, counter: state.counter + action.value } }
if (action.type === 'decrement') { return { ...state, counter: state.counter - action.value } }
if (action.type === 'change sex') { return { ...state, sex: 'female' } }
if (action.type === 'reset') { return initState3 }
return state
}
function Component3() {
const [state, dispatch] = useReducer(reducer3, initState3)
return (
<>
<div>Count: <b>{state.counter}</b></div>
<div>Sex: <b>{state.sex}</b></div>
<button onClick={() => dispatch({ type: 'increment', value: 5 })}>Increment 5</button> 
<button onClick={() => dispatch({ type: 'decrement', value: 5 })}>Decrement 5</button> 
<button onClick={() => dispatch({ type: 'change sex' })}>Change sex</button> 
<button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
</>
)
}
<Component3 />