Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

751
Views
setInterval() called twice at an interval [React js]

enter image description here

Please look at the time printed on the console.

setInterval() looks like being called twice in on interval.

I attached my code below. I'd really appreciate it if you could give me a clue to the solution.

import React, {useState} from 'react';
import AppRouter from './Router';
import {authService} from '../fbase';

function App() {
  console.log('App()');
  const [isLoggedIn, setIsLoggedIn] = useState(authService.currentUser);
  console.log(authService.currentUser);
  setInterval(() => {
    console.log(Date().toLocaleString());
    console.log('In App.js > App()');
    console.log(authService.currentUser);
  }, 5000);
  return <AppRouter isLoggedIn={isLoggedIn}></AppRouter>;
}

export default App;

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Every time a state/prop changes your component will re-render. This means that everything that is not wrapped in a hook of some kind will also re-run. I'm not sure why this happens to you, maybe authService.currentUser returns two different values, an initial (probably empty) one when mounting the component and the correct one after it does some calculations (maybe you request the user from the back-end and it takes a while to get back the response -- some more code would be helpful here).

When the actual (correct) value will be returned from the authService to your function component it will re-render thus running setInterval again.

In order to make sure this never happens it's best to wrap our functionalities in a hook. If you want to run the setInterval just ONCE (when mounting the component) we can wrap it in an useEffect with an empty dependency array:

useEffect(() => {
  setInterval(() => {
    ...
  }, 5000)
), []}

This means the hook will only run when your component first mounts.

If you need to run it based on some prop change (like when isLoggedIn changes from false to true or viceversa) you can add that to the dependency array and your interval will run every time isLoggedIn state changes:

useEffect(() => {
  setInterval(() => {
    ...
  }, 5000)
}, [ isLoggedIn ])

If you only need to run that when isLoggedIn changes from false to true you can also add an if condition in your useEffect like this:

useEffect(() => {
  if (isLoggedIn) {
    setInterval(() => {
      ...
    }, 5000)
  }
}, [ isLoggedIn ])

More than that, as Jose Antonio Castro Castro mentioned, in all of the above cases you need to use a cleanup function in order to stop the interval from running indefinitely when your component unmounts (because it has no way of knowing to stop by itself). This is achieved by returning a function from your effect:

useEffect(() => {
  const interval = setInterval(() => {
    ...
  }, 5000)

  return () => clearInterval(interval);
), []}

Don't forget that every time your component feels like re-rendering, all of your constants and functions that are called directly at the root of your component will be re-declared / re-run again.

The useEffect, useCallback, useMemo hooks help us with exactly that, but in different ways. Choose and use them wisely!

about 4 years ago · Juan Pablo Isaza Report

0

As in the comments, you need to call setInterval when you mount the component, but you need to stop the timer when it is unmounted.

const App = (props) => {
  const [count, setCount] = React.useState(0)

  React.useEffect(function appRunTimer() {
    // Creates a new timer when mount the component.
    const timer = setInterval(() => {
      console.log(Date().toLocaleString())
      console.log('In App.js > App()')
    }, 5000)
    
    // Stops the old timer when umount the component.
    return function stopTimer() {
      clearInterval(timer)
    }
  }, [])
  
  console.log('DRAW')
  return (
    <button onClick={() => {setCount(count + 1)}}>
      Click to update component's state: You click me {count} time(s)
    </button>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>

<div id="root"></div>

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!