3 回答

TA貢獻(xiàn)1942條經(jīng)驗(yàn) 獲得超3個(gè)贊
當(dāng)我們設(shè)置狀態(tài)時(shí),功能組件會(huì)從上到下重新執(zhí)行,但是當(dāng)我們使用 useState、useCallbacks 等時(shí),它們不會(huì)重新初始化為變量、函數(shù)、
所以在這種情況下,setInterval
將重新初始化每個(gè)setCount
,因?yàn)闋顟B(tài)發(fā)生了變化,
一步步
在第 1 秒會(huì)有一個(gè) setInterval,調(diào)用 setCount 組件準(zhǔn)備好重新渲染
重新渲染時(shí),開始從上到下執(zhí)行它再次看到的功能組件,
setInterval
它會(huì)觸發(fā)它,所以現(xiàn)在我們有兩個(gè)setIntervals
所以它會(huì)在每一秒添加多個(gè)setIntervals,因?yàn)槲覀儧]有清除它,所以你應(yīng)該看到瀏覽器中打印的數(shù)字不會(huì)花費(fèi)一秒鐘,但隨著時(shí)間的推移會(huì)不到一秒鐘。
您可以在不清除每次重新渲染的先前間隔的情況下獲得預(yù)期結(jié)果,useEffect
這是由于setCount
創(chuàng)建一個(gè)變量來保存設(shè)置的間隔,代碼
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 有一個(gè)鉤子,它可以保存相同的變量而無需在每個(gè)渲染上重新初始化,
const intvl = useRef(null);
....
if (intvl?.current) {
? ? clearInterval(intvl.current);
}
intvl.current = setInterval(inc, 1000);
.....

TA貢獻(xiàn)1876條經(jīng)驗(yàn) 獲得超7個(gè)贊
當(dāng)您直接使用 setInterval 時(shí)發(fā)生了什么,因?yàn)檫@是一個(gè)函數(shù),它將在狀態(tài)更改時(shí)被調(diào)用,因此將再次觸發(fā) setInterval 等等,這實(shí)際上會(huì)給您不正確的結(jié)果,因此您不應(yīng)該在沒有使用效果的情況下使用 setInterval,也在卸載時(shí)你應(yīng)該清除間隔

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