0

My problem is, I want to do an async function, that executes when the user accesses a "page" it executes, gathers data from the database, and show it to the user, it works but into a never-ending loop. Here's the code:

  const [subbbed, setSubbed] = useState([])

  async function showSubscribed() {
    
        const response = await api.get('subscribed', {
               params: {
                   hour_id: person.id
               }
           })
    
        return response.data       
    }  
       
       useEffect(()=>{
        showSubscribed().then((data)=>{
            setSubbed(data)
        })
       })

And that "setSubbed(data)" is the one that generates the loop.

Tigran Abrahamyan
  • 756
  • 1
  • 4
  • 7
Bruno D.
  • 29
  • 7

1 Answers1

3

You're not passing a second parameter to useEffect, so the callback to it will run on every render - so showSubscribed gets called on every render.

If you want showSubscribed to only run when the component is first mounted, pass an empty array as a second parameter:

useEffect(
  () => {
    showSubscribed().then((data)=>{
      setSubbed(data)
    });
  },
  []
);

Similarly, if you want the useEffect callback to only run when a particular variable changes (for example, say you have a pageNumber variable in scope), you can put that variable into the array:

useEffect(
  () => {
    showSubscribed().then((data)=>{
      setSubbed(data)
    });
  },
  [pageNumber]
);

This will result in showSubscribed being called

  • on the first render, and later,
  • whenever the pageNumber value changes

useLayoutEffect works the same way.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320