Skip to main content

Lightweight version of Redux 1: useReducer

React’s useReducer hook provides a Redux-like state management mechanism. This can be particularly useful when managing complex state logic.

Let’s consider a simple application that manages the volume of a music player.

A Simple Volume Control Application

Consider a simple volume control application that displays the current volume level and offers three buttons to update the volume: increase, decrease, and mute.

import { useReducer } from 'react'

const volumeReducer = (state, action) => {
switch (action.type) {
case "INCREASE":
return state < 100 ? state + 10 : state
case "DECREASE":
return state > 0 ? state - 10 : state
case "MUTE":
return 0
default:
return state
}
}

const App = () => {
const [volume, volumeDispatch] = useReducer(volumeReducer, 50)

return (
<div>
<div>{`Current volume is ${volume}`}</div>
<div>
<button onClick={() => volumeDispatch({ type: "INCREASE"})}>Increase</button>
<button onClick={() => volumeDispatch({ type: "DECREASE"})}>Decrease</button>
<button onClick={() => volumeDispatch({ type: "MUTE"})}>Mute</button>
</div>
</div>
)
}

export default App

Understanding useReducer

The useReducer hook provides a mechanism to create a state for an application.

The parameters for creating a state are the reducer function that handles state changes, and the initial value of the state:

const [volume, volumeDispatch] = useReducer(volumeReducer, 50)

The reducer function is similar to Redux’s reducers. It receives the current state and the action that changes the state as parameters, and returns the new state updated based on the type and possible contents of the action:

const volumeReducer = (state, action) => {
switch (action.type) {
case "INCREASE":
return state < 100 ? state + 10 : state
case "DECREASE":
return state > 0 ? state - 10 : state
case "MUTE":
return 0
default:
return state
}
}

In this example, actions have nothing but a type.

If the action’s type is “INCREASE”, it increases the volume by 10, up to a maximum of 100.

If the action’s type is “DECREASE”, it decreases the volume by 10, down to a minimum of 0.

If the action’s type is “MUTE”, it sets the volume to 0.

The useReducer function returns an array that contains an element to access the current value of the state (first element of the array), and a dispatch function (second element of the array) to change the state:

const [volume, volumeDispatch] = useReducer(volumeReducer, 50)

State changes are done exactly as in Redux, where the dispatch function is given the appropriate state-changing action as a parameter:

volumeDispatch({ type: "INCREASE" })

In conclusion, useReducer is a powerful hook that simplifies state management in React applications, providing a clean and efficient alternative to libraries like Redux.