useEffect.dev
← Back to lessons

Lesson 7. Solving infinite loops when using useEffect 2. States updating each other

The second case that can provoke an infinite loop is when, inside your useEffect, you update a state you are watching in the dependencies array. But even more diabolical, when you update another state, this other state updates the first state.

Let’s consider this example. We want to display two inputs to enter amounts in Canadian dollars (CAD) and Euros (EUR). When we enter an amount in CAD, we want to convert it into Euros, display the result in the EUR field, and vice-versa. The conversion rate is obtained from an API and changes in real-time.

Result

At first look, this code seems correct. We have a first useEffect watching the values in EUR and updating the CAD value accordingly, and a second one doing the conversion the other way, from CAD to EUR.

If you execute this code, you will get an infinite update loop, making the edition of inputs impossible (or at least very difficult, depending on how often the conversion rate changes). The reason: when we update the EUR value, we convert it to update the CAD value, which will trigger the conversion from CAD to EUR, etc. We have an infinite loop with two states mutually updating themselves.

Solving this infinite loop problem will depend on each case; it’s hard to think about a generic solution. Here, we want to update the value in CAD only if the EUR value was changed by the user input, not by conversion.

So we can keep a new local state, indicating if the user is updating the CAD or EUR field.

Result

This way, only editing the CAD field can trigger a EUR amount update and vice-versa. We solved our problem.