Search code examples
javascriptreactjssetintervaluse-effect

Periodically run useEffect for Dashboard API call


I'm looking to periodically call an API and return the response to be displayed on the page. This API is to get the message count on an Azure queue, and then display it on my dashboard.

I have tried many options but I cant seem t get it to work. I'm using setIntervalAsync to periodically call the API but currently it is only returning undefined once. Below is the code used to make the call:

export function Something() {
useEffect(() => {
  setInterval(() => 
  getProperties().then(data => {return data.Count}), 1000);
}, [])}

Any help on this will be greatly appreciated

UPDATE: Using the updated code below, I now receive the call periodically but cannot seem to get into to display.

export const Queue = () => {
  const [count, setCount] = useState()

  useEffect(() => {
    const h = setIntervalAsync(() => {
      getProperties().then(data => {
        setCount(data.Count)
        console.log("First: " + count)
      })
    }, 1000)
    console.log("Second: " + count)

    return () => { clearInterval(h) }
  }, [count])
  console.log("Third: " + count)

  return <div>{count}</div>
}

Here is where I call the function:

export let Content = () => {
  let count = Queue()
  console.log(count)
  return (
    <div className="grid">
      <h1 className="title">Queues</h1>
      <div className="row">
        <div className="column">
          <h3>count</h3>
          <h2 id='Count'>{count}</h2>
        </div>
      </div>
    </div>
  );
};

Here is a screenshot from what is returned form the console logs:

enter image description here

As you can see it is called periodically within the useEffect but doesn't reach outside periodically, only once


Solution

  • I think you call the interval right, however to ask React to do things, you need to notify it. Assuming you put this stuff in App.

      const App = () => {
        const [count, setCount] = useState(-1)
    
        useEffect(() => {
          const h = setInterval(() => {
            getProperties().then(data => {
              // trigger an update to screen
              setCount(data.Count)
            })
          }, 1000)
    
          // clean interval upon dismount
          return () => { clearInterval(h) }
    
        }, [])
    
        // this is for you to see the work
        return <div>{count}</div>
      }
    

    I added two things on top of your work:

    • setCount is used to wire your logic with an update
    • useEffect returns a destroy function to clean stuff