亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在沒有useEffect的情況下使用setInterval

如何在沒有useEffect的情況下使用setInterval

寶慕林4294392 2023-04-27 10:13:09
如果我在沒有 useEffect 的情況下使用 setInterval(line 15) 而不是它給出的結果 2^n-1(0,1,3,7,15,31,63...) 而不是 (0,1,2,3,4, ..)。所以我有一些問題1)為什么我在不使用 useEffect 的情況下直接調用 setInterval 時得到那個輸出 2)如果我更改 setCount(第 9 行)并且它通過直接使用 setInterval 而不使用 useEffect(就像我所做的那樣)給出正確的輸出,有什么辦法嗎3) 如果沒有 useEffcet 就不能使用 setInterval 那么為什么不能呢?如果我將 setInterval 放在 useEffect 中并最初渲染一次(第 12、13、14 行)而不是它給出正確的輸出......但是當我直接使用 setInterval 時我沒有得到正確的輸出。什么是差異賭注?在這兩種情況下,我都調用了一次 setInterval,但輸出是不同的。import React, {useEffect, useState } from 'react'        export default function IncorrectDependency() {        const [count,setCount]=useState(0)        const inc=()=>{        // console.log(count)        setCount(preVal=>preVal+1)    //    setCount(count+1)    }    // useEffect(()=>{    //     setInterval(inc,1000)},[]    // )    setInterval(inc,1000)            return (            <div>                <h1>{count}</h1>                           </div>        )    }
查看完整描述

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);

.....


查看完整回答
反對 回復 2023-04-27
?
幕布斯6054654

TA貢獻1876條經驗 獲得超7個贊

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



查看完整回答
反對 回復 2023-04-27
?
慕碼人2483693

TA貢獻1860條經驗 獲得超9個贊

Dan Abramov 解釋了為什么這不是一個好主意:

“這不是慣用的方法。例如,如果您有同一組件的多個實例,它將無法正常工作。它違反了規則——它在渲染過程中產生了副作用(setInterval),頁面上說你不應該這樣做做 :) 一旦你違反了規則,所有的賭注都取消了”

查看完整回答
反對 回復 2023-04-27
  • 3 回答
  • 0 關注
  • 151 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號