The traps of useEffect() – infinite loops

Paul Esch-Laurent/ @pinjasaur on Unsplash

Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.

The Effect Hook lets you perform side effects in function components.

This article assumes you already know the basics of useEffect, but as a reminder: useEffect() mimics the behavior of componentDidMount, componentDidUpdate and componentWillUnmount life cycle methods from class components. UseEffect takes two arguments, one call back function (our effect) and a dependency array. This hook watches for changes and every time one of the dependencies changes, the effect runs again. If we want it to run just once, we leave the array empty.

One of the first mistakes I made while trying the useEffect() React hook was that I was creating infinite loops. Remember, one of the usages of componentDidMount was for making API calls. Below I have an example in which I am doing just that and I am using the hook correctly. From this example I will demonstrate how errors can occur. The complete code can be found here and I encourage you to practice on it: https://codesandbox.io/s/react-useeffect-api-call-b7viy?file=/src/App.js

useEffect_react_hook_example_code

As you can see, we have two components, one which gets some data from an API (GetData), stores it in a state, then passes the data to another component (DisplayData) using props.The only job of the child component is to display some of that data.

If you look at the useEffect() hook you will see that its first argument is a function (our effect) that will make the API call. The second argument is the dependency array, which in our case it’s empty and it means we only want the effect to run once, after the component has rendered the first time (mounted).

While doing data fetching, it happened that I forgot to provide the second argument to the hook (the dependency array). If we don’t specify the dependency array, the effect will run after every render (if we set a state inside the hook, this will cause the component to re-render and the code inside the hook will run again; the state will get updated, a re-render happens, the effect will run again and so on, we got ourselves an infinite loop).

Remove the [] argument inside the useEffect() and see what happens in the console. The code should look like this:

remove_array_dependency_react_useEffect_hook

You’ll notice the API call gets made over and over again. In the end, my browser just crashes.

Another reason for creating infinite loops by mistake, is providing a dependency that always changes its value.

If in our code, as a dependency we would write the state data, this would create an infinite loop because after the effect runs, the state gets updated, the component re-renders, React sees data changed its value so it runs the effect again, the state gets updated again and so on.

Add data to your array and see what happens. The code should look like so:

wrong_dependency_react_useEffect_hook

Leave a Reply

Your email address will not be published. Required fields are marked *