1

I am new to javascript, and I made a counter. It works, however when the tab is inactive it stops and then resumes when I return to the page. Here is my code:

import React, { useEffect, useState } from 'react'

function TimeTracker(props){

    const [time, setTime] = useState(0);
    const [timerOn, setTimerOn] = useState(false);

useEffect(()=>{

        let interval = null;

        if(timerOn){
            interval = setInterval(()=>{
                setTime(prevTime => prevTime +10)
            }, 10)

        }else{
            clearInterval(interval)

        }

        return ()=> clearInterval(interval)

    },[timerOn])
    
    return(
    <div>
    
     <p>{("0" + Math.floor((time / 60000) % 60)).slice(-2)} mn</p>
     <p>{("0" + Math.floor((time / 1000) % 60)).slice(-2)} s</p>
     <button onClick={()=>setTimerOn(true)}>Start</button>
     <button onClick={()=>setTimerOn(false)}>Stop</button>


    
    </div>
    
    
    )
}

Thank you in advance for any help you can give me.

Erik ELN
  • 74
  • 1
  • 6
  • Check your code before posting it, this snippet is useless since it got an error (and not the declared one in your post) – Marius ROBERT May 30 '22 at 11:52
  • Thanks for the advice, i am new on this website! – Erik ELN May 30 '22 at 12:07
  • This might not answer the question but I recommend watching [this presentation about counters](https://www.youtube.com/watch?v=MCi6AZMkxcU). It shows the different browser quirks and issues with `setInterval`, and how to fix them. – Jacob May 30 '22 at 12:28

2 Answers2

2

On most browsers inactive tabs have low priority execution and this can affect JavaScript timers.

Thus, when you not focus on your tab, interval will not work. Its not React problem.

Check this question, I wish it help you.

Anji
  • 517
  • 2
  • 10
1

Your counter was not efficient

If you add a console.log before setTime and start the counter you will notice the extra renders

The code below will solve your issue:

import React, { useEffect, useState } from 'react'

function TimeTracker(props){

const [time, setTime] = useState(0);
const [timerOn, setTimerOn] = useState(false);

useEffect(()=>{

  let interval = null;
  if(timerOn){
      interval = setInterval(()=>{
          setTime(prevTime => prevTime +1)
      }, 1000)

  }else{
      clearInterval(interval)

  }

  return ()=> clearInterval(interval)

},[timerOn])

return(
<div>

 <p>0{Math.floor(time / 60)} mn</p>
 <p>{Math.floor(time % 60)} s</p>
 <button onClick={()=>setTimerOn(true)}>Start</button>
 <button onClick={()=>setTimerOn(false)}>Stop</button>



</div>


)
}
Zohaib
  • 119
  • 4