3 回答

TA貢獻1942條經驗 獲得超3個贊
當我們設置狀態時,功能組件會從上到下重新執行,但是當我們使用 useState、useCallbacks 等時,它們不會重新初始化為變量、函數、
所以在這種情況下,setInterval
將重新初始化每個setCount
,因為狀態發生了變化,
一步步
在第 1 秒會有一個 setInterval,調用 setCount 組件準備好重新渲染
重新渲染時,開始從上到下執行它再次看到的功能組件,
setInterval
它會觸發它,所以現在我們有兩個setIntervals
所以它會在每一秒添加多個setIntervals,因為我們沒有清除它,所以你應該看到瀏覽器中打印的數字不會花費一秒鐘,但隨著時間的推移會不到一秒鐘。
您可以在不清除每次重新渲染的先前間隔的情況下獲得預期結果,useEffect
這是由于setCount
創建一個變量來保存設置的間隔,代碼
const interval = null;
//this should be declare out side the component,
//because if we declare it inside the component it will redeclare,
//and the reference to the previous setInterval will be lost in that case no-way to clear the setInterval.
export default function IncorrectDependency() {
? ? ....
? ? if (interval) {
? ? ? ? clearInterval(interval);
? ? }
? ? interval = setInterval(inc, 1000);
? ? ....
?}
或者 React 有一個鉤子,它可以保存相同的變量而無需在每個渲染上重新初始化,
const intvl = useRef(null);
....
if (intvl?.current) {
? ? clearInterval(intvl.current);
}
intvl.current = setInterval(inc, 1000);
.....

TA貢獻1876條經驗 獲得超7個贊
當您直接使用 setInterval 時發生了什么,因為這是一個函數,它將在狀態更改時被調用,因此將再次觸發 setInterval 等等,這實際上會給您不正確的結果,因此您不應該在沒有使用效果的情況下使用 setInterval,也在卸載時你應該清除間隔

TA貢獻1860條經驗 獲得超9個贊
Dan Abramov 解釋了為什么這不是一個好主意:
“這不是慣用的方法。例如,如果您有同一組件的多個實例,它將無法正常工作。它違反了規則——它在渲染過程中產生了副作用(setInterval),頁面上說你不應該這樣做做 :) 一旦你違反了規則,所有的賭注都取消了”
添加回答
舉報