Home > database >  Can you tell me why the second in incrementing in even numbers in the stopwatch?
Can you tell me why the second in incrementing in even numbers in the stopwatch?

Time:06-03

I was trying to create a stopwatch, when I run it, it's counting the seconds in even numbers like 0 - 2 - 4 - 6....... I don't understand why.

I don't find any error in the code. if anyone can help, it would be helpful


export default function Stopwatch() {
    let [ispaused,setIspaused ] = useState(false);
    let [seconds, setSeconds] = useState (0);

    let secondsref = useRef(seconds)
    let ispausedRef = useRef(ispaused);
    let watch = useRef(0);
    
    let initTicker= ()=>{
        ispausedRef.current = true
        setIspaused(true);
        
      }
      let stopTicker=()=>{
        ispausedRef.current = false
        setIspaused(false)
        //setSecondsleft(secondsleftRef.current);
      }
      
      let resethndler = ()=>{
        setIspaused(false)
        ispausedRef.current = false;
        secondsref.current=0;
        setSeconds(0);
        
      }

      let Tick = ()=>{
        secondsref.current =1;
        setSeconds(secondsref.current);
}

 useEffect(()=>{
    
watch.current = setInterval(()=>{
    if (!ispausedRef.current){
        return;
        }
    Tick();
},1000)
 },[])     

let percantage = ((seconds`)/60)*100

  return (
    <div>
      <div className='stopwatch'>
          
          <CircularProgressbar
          ssbar value={percantage} text={`0${parseInt(seconds/60)}`.slice(-2)  ":"  `0${seconds`}`.slice(-2)} />
          
          </div>
}

CodePudding user response:

Fasten your seat belt it will be fun! :)

I assume you're using <StrictMode>. This mode will mount / unmount / remount your components to identify potential issues in lifecycle. Only on development environment. You can read more about it from React documentation.

So once that is said, your component is in fact mounted twice so you're creating 2 intervals. And as React batches setState, it seems to count numbers 2 by 2. But it's in fact 2 different intervals.

So solution here is in your useEffect, which must return a cleanup function, which will destroy your interval

useEffect(() => {
  ...
  return () => clearInterval(watch.current)
}, [])

CodePudding user response:

As @dbuchet said, it may be because of <StrictMode>.

I've made a (bit simplified) version in codesandbox. Notice the commented out StrictMode in index.js. The counter works correct.

  • Related