繁体   English   中英

ReactJS-将setTimeout()与if / else语句一起使用

[英]ReactJS - Using setTimeout() with if/else statement

我正在使用React pomodoro时钟,并且无法通过setTimeout()加入if / else。 这是我的代码:

React.useEffect(() => {
    if(props.isOn === true) {
      if(props.timeLeft <= 0) {
        setTimeout(function() {
          if(props.activeClockType === 'Session') {
            props.handleClockType('Break');
            props.handleTimeLeft(props.breakLength * 60);
          } else {
            props.handleClockType('Session');
            props.handleTimeLeft(props.sessionLength * 60);
          }
        }, 1000);
      }
      const id = setInterval(count, 1000);
      return () => clearInterval(id);
    }
  });

当时钟转到00:00时,它会停止1秒钟,然后显示Break,并将计时器设置为breakLength。 很好,但是经过1秒后,它没有倒计时,而是变回Session并计算sessionLength。

当我删除setTimeout (在CodePen中注释)时,它工作良好,但并没有在00:00停止1秒,而是在Break时立即更改了看起来难看的东西。

如何在计数其他activeClockType之前使其在00:00停止1秒?

我整夜都在寻找任何线索,但我仍然不知道哪里出了问题。 我试图将setTimeout与if的每种可能组合都放在同一位置。 这个话题,我怀疑我应该使用clearTimeout,但也可以尝试以任何组合使用它,但是一无所获。

或者,也许我应该尝试使用useEffect()以外的另一种方式来运行倒计时? 早些时候,我使用componentWillReceiveProps在类component (在CodePen中进行了注释)中设置了工作计时器,但该计时器已被弃用,并且我尝试在其他函数上进行更改也没有任何效果。 我不完全了解此效果挂钩,但这是我发现计数良好的唯一方法。 它比类组件要短。

是我在CodePen上的完整代码

先感谢您。

我认为这里有两个问题:

1)每次使用挂钩设置状态时,都会触发React.useEffect,如果将状态设置两次,则React.useEffect将触发两次。

2)使用setTimeout替换setInterval以避免更新状态太多次。

问题如下所示:

  React.useEffect(() => {
    if(props.isOn === true) {
      if(props.timeLeft <= 0 && !changeClockType) {
        setTimeout(function() {
          if(props.activeClockType === 'Session') {
            props.handleClockType('Break');   // ==> Fired update and then excuted React.useEffect
            props.handleTimeLeft(props.breakLength * 60); //  ==> Fired update again and then excuted React.useEffect again
          } else {
            props.handleClockType('Session');
            props.handleTimeLeft(props.sessionLength * 60);
          }
        }, 1000);
      }
      const id = setTimeout(count, 1000);  // ==> modify setInterval to setTimeout 
      return () => clearInterval(id);
    }

  });

我尝试像这样修改代码:

let changeClockType = false;  // ==> Should be put here because it couldn't be put in the function component
function Timer(props) {

  const count = () => props.handleTimeLeft(props.timeLeft - 1);

  function startStop() {
    props.handleIsOn(props.isOn === false ? true : false);
  }

  React.useEffect(() => {
    console.log("step 1");
    if(props.isOn === true) {   console.log("step 2");
      if(props.timeLeft <= 0 && !changeClockType) {   console.log("step 3");
        setTimeout(function() {
          if(props.activeClockType === 'Session') {   console.log("step 4");
            changeClockType = true;
            props.handleClockType('Break');   // ==> Fired update and then excuted React.useEffect
            console.log("Change to Break")
            props.handleTimeLeft(props.breakLength * 60); //  ==> Fired update again and then excuted React.useEffect again
            changeClockType = false;
            console.log("Set breakLength")
          } else {   console.log("step 5");
            changeClockType = true;
            props.handleClockType('Session');
            props.handleTimeLeft(props.sessionLength * 60);
            changeClockType = false;
          }
        }, 1000);
      }
      const id = setTimeout(count, 1000);  // ==> modify setInterval to setTimeout 
      return () => clearInterval(id);
    }
  });

该代码不是很干净,但是可以很好地运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM