useEffect.dev
← Back to lessons

Lesson 11. Simplify state update logic with reducers 1. Meet useReducer

Let’s consider the async pattern we saw in a previous lesson. We had a state containing three attributes:

  • a loading flag, set to true when the HTTP request is in progress,
  • an error flag, set to true if the request returned an error,
  • and the result of the call.

Depending on the logic we want to implement, it might not make sense to update the result without setting the loading attribute to false. Nor might it to set the error flag and at the same time the loading flag to true. In other words, only some updates should be possible.

Here is where using the reducer pattern can be useful. The first step is to define the actions that will update the state. In our scenario, we can imagine the following actions:

  • one to say that we initiated the request,
  • one to say that the request succeeded,
  • one to say that an error occurred.

Each of these actions will update some values in the state:

  • the first one will set the loading attribute to true and error to false,
  • the second will update the result attribute and set loading to false,
  • the third one will set error to true and loading to false.

To handle the updates, we have to define a reducer function. If you used Redux, you should be familiar with it. It is a function that takes two parameters: the current state and an action. Traditionally, an action is an object with a type attribute and possibly some other attributes specific to the action. Based on this action and the current state, the reducer function must return a new version of the state.

Enough theory, let’s see an example.