Home > database >  Show countdown when holding button then show alert
Show countdown when holding button then show alert

Time:01-05

I'm trying to create a button, which when hold shows a countdown of 3 seconds, if kept on hold for 3 seconds it shows an alert, but for some reason the countdown doesn't reset properly AND the alert fires up anyway, at every click (after the timeout)

my code is:

const [showCountdown, setShowCountdown] = useState(false)
const [holdTimer, setHoldTimer] = useState(3)

var timer = 0, interval;
const refreshDown = () => {
    setShowCountdown(true)
    interval = setInterval(function(){       
        setHoldTimer((t) => t - 1)
    },1000);
    timer = setTimeout(function(){
        if (confirm('Refresh page?')){
            window.location.reload()
        }
    },3000)
}
const refreshUp = () => {
    clearTimeout(timer)
    clearInterval(interval)
    setShowCountdown(false)
    setHoldTimer(3)
}

my html button has these two:

<svg onm ouseDown={() => refreshDown()} onm ouseUp={() => refreshUp()}>
  ...
</svg>

CodePudding user response:

Have you tried with useRef ?

const timer = useRef();
  const interval = useRef();
  const refreshDown = () => {
    setShowCountdown(true);
    interval.current = setInterval(function () {
      setHoldTimer((t) => t - 1);
    }, 1000);
    timer.current = setTimeout(function () {
      if (confirm("Refresh page?")) {
        window.location.reload();
      }
    }, 3000);
  };
  const refreshUp = () => {
    clearTimeout(timer.current);
    clearInterval(interval.current);
    setShowCountdown(false);
    setHoldTimer(3);
  };

CodePudding user response:

React component is rerendered each time state or props are changed. When setHoldTimer is executed, it changes the state. It causes reexecuttion of component’s code, so local variables “timer” and “interval” are declared again with values “0” and “undefined”, also new “refreshUp” function is created referencing new “timer” and “interval”. When you release the mouse, new “refreshUp” is called, interval and timeout are not cleared.

Try to define timer and interval as a state or with “useRef”. This way they will not be redefined during rerender.

  • Related