反应倒数计时器无法停止功能 [英] React Countdown Timer unable to make a stop function

查看:53
本文介绍了反应倒数计时器无法停止功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我几乎是 React 的新手.在这个应用程序中,我正在使用 Hooks!我制作了一个倒数计时器,它会在登录后几秒钟内显示.我无法让它在单击按钮时停止.我需要一些有关此的建议,因为过去 2 天我一直在为此苦苦挣扎.到目前为止,这是我的代码:(请帮忙)

I am practically new to React. In this App I am using Hooks! I've made a Countdown Timer that will show in a few seconds after logging in. I am unable to make it stop on a button click. I need some advise on this as I've been struggling for the past 2 days with this. This is my code so far: (Please Help)

function Admin() {
    const [isTimerOpen, setTimmer] = useState(false);
    let history = useHistory();

    // SET BY THE ADMIN
    var minutesToCountDown = 0.9;
    // TRANSFORM INTO SECONDS
    var transformMinutesToSeconds = minutesToCountDown * 60
    // KEEP A STATE
    const [counterValue, setCounterValue] = useState(0);
    const [isTimmerStoped, setStopTimer] = useState(false);

    // FUNCTION TO HAPPEN EVERY 1 SECOND
    function timeIt() {
        if (isTimmerStoped === false) {
            transformMinutesToSeconds--
            setCounterValue(transformMinutesToSeconds)
            console.log("Timer is on: ", transformMinutesToSeconds)

            if (transformMinutesToSeconds === 0) {
                clearInterval(interval)
                setStopTimer(true)
            }
        } else {
            setStopTimer(true)
            clearInterval(interval)
        }
    }

    // STARTS THE COUNTDOWN
    var interval;
    const startCountdown = () => {
        interval = setInterval(timeIt, 1000)
    }

    const stopCountdown = () => {
        console.log("Stop Timer")
        setStopTimer(true);
        setCounterValue(0);
        setTimmer(false);
    }

    // ADD 0 IN FRONT ON THE TIME REMAINING
    const addLeadingZeros = value => {
        value = String(value);
        while (value.length < 2) {
            value = `0${value}`;
        }
        return value;
    };

    // CONVERT SECONDS INTO TIME REMAINING
    function convertSeconds(seconds) {
        var min = Math.floor(seconds / 60);
        var sec = seconds % 60;
        return addLeadingZeros(min) + ':' + addLeadingZeros(sec)
    }

    const logOutUser = () => {
        logout();
        return history.push(mainRoute)
    }

    function setTimer() {
        const timer = setTimeout(() => {
            setTimmer(true)
            console.log('This will run after 3 seconds!')
            startCountdown()

        }, sessionTimeout);
        return () => clearTimeout(timer);
    }

    useEffect(() => {
        if (isTimmerStoped === false) {
            console.log('Effect Starting', isTimmerStoped)
            setTimer()
        } else {
            console.log('Effect Stopping', isTimmerStoped)
            stopCountdown()
        }

      }, [isTimmerStoped, setStopTimer, minutesToCountDown]);



    return <React.Fragment>
            <CssBaseline />
            <Container disableGutters maxWidth={false}>
                <NavigationBar handleSignOut={logOutUser}/>
                <TimerContent 
                    timeRemaining={convertSeconds(counterValue)}
                    isTimerAlertOpen={isTimerOpen}
                    extendSessionBtn={stopCountdown}
                    logoutBtn={logOutUser}  
                    clickOutsideButton={stopCountdown}/>
            </Container>
    </React.Fragment>  
}

export default Admin;

推荐答案

你应该做两件事.

  1. 使 interval 变量成为参考.这样它的价值在每个进口的地方都是独一无二的.注意:仅在组件上方创建一个变量是一个坏主意,因为该变量将在导入 Admin 组件的每个组件之间共享,这会导致错误.
  1. Make the interval variable a ref. This way it's value will be unique every where it imported. Note: Just creating a variable above the component is a bad idea because that variable will be shared between each component that imports the Admin component, which will lead to bugs.

错误

let interval;

function Admin() {
  //... code here

  // STARTS THE COUNTDOWN
  // var interval; Remove from here
  const startCountdown = () => {
      interval = setInterval(timeIt, 1000)
  }

  //... code here
}

export default Admin;

对了

function Admin() {
  const interval = React.useRef(); 
  //... code here

  // STARTS THE COUNTDOWN
  // var interval; Remove from here
  const startCountdown = () => {
      interval.current = setInterval(timeIt, 1000)
  }

  //... code here
}

export default Admin;

  1. clearInterval 添加到您的 stopCountdown 函数.您可以删除timeIt 函数中的clearInterval 并将其移动到stopCountdown 中.请看一下这个 codepen 我用来演示
  1. Add clearInterval to your stopCountdown function. You can remove the clearInterval in the timeIt function and move it into stopCountdown. Please take a look at this codepen I made to demostrate

const stopCountdown = () => {
  console.log("Stop Timer")
  setStopTimer(true);
  setCounterValue(0);
  setTimmer(false);
  clearInterval(interval.current) // Clear the interval here
}

这篇关于反应倒数计时器无法停止功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆