[英]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
(如果上次调用返回),如果automatic
为true
,它将创建一个新的间隔循环,并返回当前间隔的新清理 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.