我正在用 React 構建一個簡單的時鐘應用程式。目前該countDown()功能有效,但我希望用戶能夠通過按下按鈕來停止/啟動時鐘。我有一個狀態布林值paused,當用戶單擊按鈕時它被反轉。問題在于,在 的值被反轉之后,傳遞給的函式內部paused的參考似乎正在訪問 的默認值,而不是更新的值。pausedcountDown()setInterval()paused
function Clock(){
const [sec, setSecs] = useState(sessionLength * 60);
const [paused, setPaused] = useState(false);
const playPause = () => {
setPaused(paused => !paused);
};
const countDown = () => {
if(!paused){
setSecs(sec => sec - 1)
}
}
useEffect(() => {
const interval = setInterval(() => {
countDown();
}, 1000);
return () => {
clearInterval(interval);
};
}, []);
我假設它與setState()React 中呼叫的異步性質和/或使用正則運算式時范圍/背景關系的性質有關。但是,我無法通過閱讀與這些概念相關的檔案來確定發生了什么。
我可以想出一些解決方法,讓我的應用程式按需要運行。但是我想了解我目前的方法有什么問題。我將不勝感激任何人都可以對此有所了解!
uj5u.com熱心網友回復:
在您的代碼中,useEffect僅在安裝組件時呼叫一次。
里面注冊的倒計時函式在呼叫的時候會有它的初始值useEffect/setInterval。所以paused只有當你最初安裝組件時才會有這個值。因為您沒有直接呼叫 countDown 或在您的內部更新其值useEffect,所以它不會更新。
我認為你可以這樣解決這個問題:
interval.current = useRef(null);
const countDown = () => {
if(!paused){
setSecs(sec => sec - 1)
}
}
useEffect(() => {
clearInterval(interval.current);
interval.current = setInterval(countDown, 1000);
return () => {
clearInterval(interval.current);
};
}, [paused]);
你useEffect的值取決于paused它需要創建一個新的間隔(具有不同的倒計時功能)。這useEffect不僅會觸發掛載,還會觸發每次paused更改。因此,一種解決方案是清除間隔并使用不同的回呼函式開始新的間隔。
編輯:您實際上可以改進它,因為您只希望在 countDown 函式實際執行某些操作時運行間隔,因此這也應該有效:
useEffect(() => {
clearInterval(interval.current);
if(!paused) {
interval.current = setInterval(countDown, 1000);
}
return () => {
clearInterval(interval.current);
};
}, [paused]);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/475514.html
標籤:javascript 反应 设置间隔 使用效果 使用状态
上一篇:異步呼叫堆疊執行間隙
