loading...
Cover image for Infinite Loops Inside useEffect

Infinite Loops Inside useEffect

loripb profile image Lori "Lei" Boyd ・2 min read

Recently, I came across a bug when using the useEffect hook. I intended to utilize the functionality of the lifecycle method componentDidMount, but useEffect doesn't work precisely the same way.

The Bug

useEffect(()=> {
  fetch("http://localhost:3000/categories")
    .then(resp => resp.json())
    .then(categoriesArray => {
       this.setState({
         categories: categoriesArray
       })
    })
})

Whenever we ran the application, the fetch was successful but continued to fetch infinitely.

The Solution

After a few minutes of google searching the problem, we came across a StackOverflow post that gave us a simple solution.

useEffect(()=> {
  fetch("http://localhost:3000/categories")
    .then(resp => resp.json())
    .then(categoriesArray => {
       this.setState({
         categories: categoriesArray
       })
    })
},[])

A user suggested that adding empty brackets as a second argument will fix the infinite fetching.

Alt Text

A Bit About useEffect

useEffect lets you perform side effects in function components. Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects. To put it simply, useEffect is like a combination of componentDidMount, componentWillUnmount, and componentDidUpdate.

So what's happening when we run our broken code? When the component first renders and mounts, the fetch is called and then sets the state for categories that cause the component to render again. This blog post that Andrew Myint wrote explains this pretty well.

The second argument will tell useEffect not to render unless the said variable changed between renders. Andrew Myint's post uses a variable inside brackets as the second argument. I think the empty brackets also work because there is no trigger to run useEffect again, it'll run only once, after the component mounts.

Posted on by:

Discussion

markdown guide
 

useEffect really gets everyone. Pretty tough to grasp.