简体   繁体   English

如何清除 React 中的间隔

[英]How to clear the interval in React

I am building a stopwatch by using useState hooks in react.js but while implementing pause functionality I have noticed that I am not able to clear the interval.我正在通过在 react.js 中使用useState挂钩来构建秒表,但是在实现暂停功能时,我注意到我无法清除间隔。 I am new and I have tried many things but still it doesn't work.我是新手,我尝试了很多东西,但仍然没有用。 If anyone can help me fix the code or suggest me other way.如果有人可以帮助我修复代码或建议我以其他方式。

Here is my code:这是我的代码:

function App() {
  const [stopwatch, setStopwatch] = useState({
    hour: 0,
    min: 0,
    sec: 0,
    secElapsed: 0,
    minElapsed: 0,
  });

  const [buttonState, setButtonState] = useState({
    start: true,
    stop: false,
    pause: false,
    resume: false,
  });

  var interval = null;

  function onStart() {
    // i want to clear this interval when the onPause function is called
    var clrInt = setInterval(() => {
      setStopwatch(prevValue => {
        prevValue.secElapsed++;
        return {
          hour: Math.floor(prevValue.secElapsed / 3600),
          minElapsed: Math.floor((prevValue.secElapsed + 1) / 60),
          min: prevValue.minElapsed % 60,
          sec: prevValue.secElapsed % 60,
          secElapsed: prevValue.secElapsed,
        };
      });
    }, 1000);

    setButtonState(prevValue => {
      return {
        ...prevValue,
        start: false,
        pause: true,
        stop: true,
      };
    });
    interval = clrInt;
  }

  function onPause() {
    setButtonState(prevValue => {
      return {
        ...prevValue,
        pause: false,
        resume: true,
      };
    });

    // i want to clear the interval in onStart function here
    clearInterval(interval);
  }

  return (
    <div>
      <h1>
        {stopwatch.hour < 10 ? '0' + stopwatch.hour : stopwatch.hour}:
        {stopwatch.min < 10 ? '0' + stopwatch.min : stopwatch.min}:
        {stopwatch.sec < 10 ? '0' + stopwatch.sec : stopwatch.sec}
      </h1>
      {buttonState.start ? <button onClick={onStart}>Start</button> : null}
      {buttonState.pause ? <button onClick={onPause}>Pause</button> : null}
      {buttonState.stop ? <button>Stop</button> : null}
      {buttonState.resume ? <button>Resume</button> : null}
    </div>
  );
}

Declaring a variable inside the function component will run every time the component is rendered.在 function 组件内声明一个变量将在每次渲染组件时运行。 You need to capture the interval in a useState like您需要在 useState 中捕获间隔,例如

var [intervalState, setIntervalState] = useState(null)

...

function onStart() {
   var clearInterval = setInterval(() => {
      ...
   })

   setIntervalState(clearInterval)
}

This will make sure your clearInterval value will persist across rerenders这将确保您的 clearInterval 值将在重新渲染中持续存在

I don't think the interval fits into the component's state.我认为间隔不适合组件的 state。 Instead, I would use the useRef hook to keep it through the component's lifetime.相反,我会使用useRef钩子在组件的整个生命周期中保持它。

Anyways , it's good that you start thinking in hooks:)无论如何,你开始思考钩子很好:)

A cleaner way is to implement something like useInterval :一种更简洁的方法是实现类似useInterval的东西:

const [isRunning, setIsRunning] = useState(true)

useInterval(() => {
    // Your custom logic here
}, isRunning ? 1000 : null)

const onPause = () => {
    // ...
    setIsRunning(false)
}

Here 'sa demo with an actual implementation of the hook. 是一个实际实现钩子的演示。

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

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