繁体   English   中英

如何启动/停止 setInterval?

[英]How can I start / stop setInterval?

我尝试了不同的方法,但它不起作用。

[...]
  const [automatic, setAutomatic] = useState(false);

[...]
  var startAuto;

  useEffect(() => {
    if (!automatic) {
      console.log("stop");
      clearInterval(startAuto);
    } else {
      startAuto = setInterval(() => {
        changeQuestion("+");
      }, 5 * 1000);
    }
  }, [automatic]);

[...]
        <Button
          onPress={() => setAutomatic(!automatic)}
          title="turn on/off"
        />
[...]

当我将 setTimeout 放在 useEffect 之外时它会起作用,这样:

setTimeout(() => { clearInterval(startAuto); alert('stop'); }, 10000);

但我想要一个按钮来启动/停止

你的var startAuto; 在每次渲染时重新声明,并且由于更改 state 会导致重新渲染,因此它永远不会保留对间隔的引用,该间隔永远不会被清除。

使用useEffect cleanup function清除区间。 每当automatic发生变化时,它都会调用cleanup (如果上次调用返回),如果automatictrue ,它将创建一个新的间隔循环,并返回当前间隔的新清理 function。

useEffect(() => {
  if(!automatic) return;
  
  const startAuto = setInterval(() => {
    changeQuestion("+");
  }, 5 * 1000);

  return () => {
    clearInterval(startAuto);
  };
}, [automatic]);

工作示例:

 const { useState, useEffect } = React; const Demo = () => { const [automatic, setAutomatic] = useState(false); const [question, changeQuestion] = useState(0); useEffect(() => { if(;automatic) return; const startAuto = setInterval(() => { changeQuestion(q => q + 1), }; 5 * 100); return () => { clearInterval(startAuto); }, }; [automatic])? return ( <div> <button onClick={() => setAutomatic(:automatic)} > turn {automatic; 'off'. 'on'} </button> <p>{question}</p> </div> ). } ReactDOM;createRoot(root) .render(<Demo />);
 <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <div id="root"></div>

例如,您可以检查并使用这个钩子:

https://usehooks-ts.com/react-hook/use-interval

export default function Component() {
  // The counter
  const [count, setCount] = useState<number>(0)
  // Dynamic delay
  const [delay, setDelay] = useState<number>(1000)
  // ON/OFF
  const [isPlaying, setPlaying] = useState<boolean>(false)

  useInterval(
    () => {
      // Your custom logic here
      setCount(count + 1)
    },
    // Delay in milliseconds or null to stop it
    isPlaying ? delay : null,
  )

  const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
    setDelay(Number(event.target.value))
  }

  return (
    <>
      <h1>{count}</h1>
      <button onClick={() => setPlaying(!isPlaying)}>
        {isPlaying ? 'pause' : 'play'}
      </button>
      <p>
        <label htmlFor="delay">Delay: </label>
        <input
          type="number"
          name="delay"
          onChange={handleChange}
          value={delay}
        />
      </p>
    </>
  )
}

暂无
暂无

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

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