首页 > 解决方案 > 在 React 中单击按钮时如何停止计时器?

问题描述

在 reactjs 中单击我的按钮时,如何停止两个计时器。

我注意到,当我的计时器运行时,我的整个组件每次都重新渲染如何避免这部分。

export default function App() {
  const [counterSecond, setCounterSecond] = React.useState(0);
  const [counter, setCounter] = React.useState(120);
  const [time, setTime] = React.useState("");

  React.useEffect(() => {
    setTimeout(() => setCounterSecond(counterSecond + 1), 1000);
    setTimeout(() => setCounter(counter - 1), 1000);
  }, [counterSecond , counter]);



  const handletimer = () => {
    setTime(counterSecond);
  };

  return (
    <div className="App">
      <div>Countdown: {counterSecond}</div>
      <div>Countdown Reverse: {counter}</div>
      <div>time: {time} </div>
      <button onClick={handletimer}>Submit</button>
    </div>
  );
}

标签: reactjs

解决方案


最好的方法是添加一个state代表工作的变量status。即:“工作”,“暂停”并切换它。

此外,如果组件被卸载,您需要取消订阅超时以避免状态更新。

这是一个示例,您可以在其中停止和恢复计时器:

export default function App() {
  const [counterSecond, setCounterSecond] = React.useState(0);
  const [counter, setCounter] = React.useState(120);
  const [time, setTime] = React.useState("");
  const [status, setStatus] = React.useState("working");

  React.useEffect(() => {
    let secondCounterId;
    let counterId;
    if (status === "working") {
      secondCounterId = setTimeout(
        () => setCounterSecond(counterSecond + 1),
        1000
      );
      counterId = setTimeout(() => setCounter(counter - 1), 1000);
    }

    return () => {
      clearTimeout(counterId);
      clearTimeout(secondCounterId);
    };
  }, [counterSecond, counter, status]);

  const handletimer = () => {
    setTime(counterSecond);
  };
  const stopTimers = () => {
    setStatus("paused");
  };
  const resume = () => {
    setStatus("working");
  };

  return (
    <div className="App">
      <div>Countdown: {counterSecond}</div>
      <div>Countdown Reverse: {counter}</div>
      <div>time: {time} </div>
      <button onClick={handletimer}>Submit</button>
      <button onClick={stopTimers}>Stop</button>
      <button onClick={resume}>resume</button>
    </div>
  );
}

和一个有效的密码箱


推荐阅读