![](/img/trans.png)
[英]setInterval() keeps running even after clearing it using clearInterval()
[英]React: Setinterval is not stopping even after clearing the timer using clearInterval
我制作了一個基本的幻燈片演示,其中選中復選框幻燈片已啟用。 問題是即使我取消選中復選框,一旦啟用幻燈片放映也無法禁用。 根據 muy 的理解,我正在學習計時器並使存儲計時器的 state 無效,但幻燈片繼續放映。
具體來說,這部分在復選框更新時被調用:
useEffect(() => {
if (isTrue) {
setSlideTimer(() => {
return setInterval(() => {
forwardButton.current.click();
}, slideDuration);
});
} else {
clearInterval(slideTimer);
setSlideTimer(null);
}
}, [isTrue]);
從瀏覽器日志中可以明顯看出計時器確實被清除了。 雖然有警告"... component is changing an uncontrolled input of type checkbox to be controlled"
,但我不確定這是否是罪魁禍首。
問題是您缺少對sliderTimer
state 的依賴。
useEffect(() => {
if (isTrue) {
setSlideTimer(() => {
return setInterval(() => {
forwardButton.current.click();
}, slideDuration);
});
} else {
clearInterval(slideTimer);
setSlideTimer(null);
}
}, [isTrue]);
通常不要將計時器 ID 存儲在 state 中。如果您需要在useEffect
掛鈎之外訪問計時器 ID,則使用 React ref,否則只需將其緩存在useEffect
掛鈎的回調中。 在這種情況下,您將希望使用 ref 來保存sliderTimer
id 值,以便在組件卸載的情況下也可以清除它。
例子:
const sliderTimerRef = React.useRef();
useEffect(() => {
// Clear any running intervals on component unmount
return () => clearInterval(sliderTimerRef.current);
}, []);
useEffect(() => {
if (isTrue && forwardButton.current) {
sliderTimerRef.current = setInterval(
forwardButton.current.click,
slideDuration
);
} else {
clearInterval(sliderTimerRef.current);
}
}, [isTrue]);
從瀏覽器日志中可以明顯看出計時器確實被清除了。 雖然有警告
"... component is changing an uncontrolled input of type checkbox to be controlled"
,但我不確定這是否是罪魁禍首。
當value
或checked
prop 從未定義值更改為已定義值時,通常會出現這種情況。 確保選中的 state 是最初定義的,即使只是false
。
嘗試這個!
useEffect(() => {
let interval;
if (isChecked) {
interval = setInterval(() => {
forwardButton.current.click();
}, 1000); // change it
}
return function cleanup() {
clearInterval(interval);
console.log('Clear timer');
};
}, [isChecked]);
另一種方法是使用setTimeout()
方法。 為此,您需要創建一個新的 state clicks
(或任何其他名稱),每次更改時都會觸發useEffect
,從而使setTimeout
像setInterval
一樣工作
const [clicks, setClicks] = useState(0)
useEffect(() => {
if(isChecked){
setTimeout(() => {
forwardButton.current.click()
setClicks(clicks + 1)
}, slideDuration)
}
}, [isChecked, clicks])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.