The traps of useEffect() - infinite loops
Arika O
Posted on June 12, 2020
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
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:
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:
Image source: Jantine Doornbos/ @jantined on Unsplash
Posted on June 12, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 7, 2022