Manage complex internal state with the Reducer Hook

Photo by John Barkiple on Unsplash

In one of my previous posts I re-implemented a simple “to do” class component to a function component with useState and useEffect hooks.

As it has been pointed out, the case is a good example for using useReducer in place of useState.

According to the official documentation, useReducer is:

an alternative to useState. Accepts a reducer of type (state, action) => newState, and returns the current state paired with a dispatch method.

and works exactly as a reducer in Redux. The article further mentions that:

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.

Replacing state management functions with a reducer

The “to do” component did in fact use may separate methods to manage the state. For instance this was the function to add a new item to the list:

The function can be refactored out of the component and incorporated as one of the cases in the reducer function:

Updating references to state and state setters

Multiple calls to useState can now be replaced with a single call to useReducer:

From there, any call to set... functions needs to be replaced with an action dispatch, e.g.:

Summary

In the end, there is no much difference in code volume, however we can claim that complexity has been somewhat reduced by extracting all state management out of the component function. On the other hand we had to introduce actions to replace all of the removed functions.

A single call to useReducer replacing multiple calls to setState might make the call more readable. The inline calls to dispatch inside event handlers (which also define actions) look a little flaky in comparison, so leaving the state management functions with their inner logic delegated to the reducer is another possibility.

Take a look at the final code:

More on Hooks

This article is the third part of my short series on React Hooks: