偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

精準(zhǔn)解析 useLayoutEffect 與 useEffect 的執(zhí)行時(shí)機(jī)

開(kāi)發(fā) 前端
當(dāng)我們使用 useLayoutEffect 時(shí)他可能會(huì)覆蓋你想要執(zhí)行的渲染內(nèi)容,也有可能會(huì)阻塞你的正常渲染過(guò)程,因此我們?cè)谑褂盟鼤r(shí),需要精確把控他的執(zhí)行時(shí)機(jī),防止出現(xiàn)你不想看到的結(jié)果

我們前面花了大量篇幅,從基礎(chǔ)、理論、實(shí)踐、總結(jié)幾個(gè)方面,全方位的為大家分析了 useEffect。除此之外,React 還提供了一個(gè)與 useEffect 幾乎一樣的 hook,它就是useLayoutEffect。

我們約定,useEffect 傳入的第一個(gè)參數(shù)為 effect,useLayoutEffect 傳入的第一個(gè)參數(shù)為 layoutEffect。

他們的語(yǔ)法為:

// 中括號(hào)表示參數(shù)可選
useEffect(effect[, deps])
useLayoutEffect(layoutEffect[, deps])

兩個(gè) hook 有高度相似的語(yǔ)義。

第一個(gè)參數(shù) layoutEffect 為一個(gè)函數(shù),定義為副作用執(zhí)行邏輯,我們也可以在 layoutEffect 中定義返回函數(shù)。當(dāng)依賴項(xiàng)發(fā)生了變化時(shí),返回函數(shù)會(huì)使用依賴項(xiàng)舊值首先執(zhí)行,然后再執(zhí)行 layoutEffect。

useLayoutEffect(() => {

  // ...
  
  return () => {}
}, [state])

第二個(gè)參數(shù)為依賴項(xiàng)數(shù)組。React 內(nèi)部會(huì)使用 Object.is 去比較依賴項(xiàng)是否發(fā)生了變化,我們通常會(huì)選擇使用 state 或者 props 等響應(yīng)性數(shù)據(jù)作為依賴項(xiàng)。依賴項(xiàng)也可以不傳,此時(shí) layoutEffect 在每次狀態(tài)發(fā)生變化時(shí)都會(huì)執(zhí)行。

useLayoutEffect 與 useEffect 唯一的區(qū)別在于 effect 與 layoutEffect 執(zhí)行時(shí)機(jī)的不同。

我們借助一個(gè)例子來(lái)仔細(xì)分析他們的準(zhǔn)確執(zhí)行時(shí)機(jī)。

首先是 useEffect。

const [count, setCount] = useState(0)

useEffect(() => {
  document.title = `React ${count}`
})

effect 會(huì)在組件渲染完成之后執(zhí)行。這里組件渲染完成的意思是當(dāng)組件內(nèi)容已經(jīng)呈現(xiàn)在頁(yè)面上之后,effect 再執(zhí)行,具體的步驟如下圖所示:

在事件循環(huán)中, effect 是被定義為宏任務(wù),在下一輪循環(huán)執(zhí)行。

然后是 useLayoutEffect。

const [count, setCount] = useState(0)

useLayoutEffect(() => {
  document.title = `React ${count}`
})

layoutEffect 會(huì)在組件渲染之前執(zhí)行。具體的步驟如下圖。

但是這里如果只是這樣理解的話,估計(jì)很多人并不太清晰具體是怎么回事。因?yàn)檫@樣的表達(dá)并沒(méi)有說(shuō)清楚具體的執(zhí)行時(shí)刻。更準(zhǔn)確的說(shuō)法是在 commit 之后,組件內(nèi)容繪制呈現(xiàn)到屏幕之前。

例如我們有這樣一段代碼。

// 此時(shí)已經(jīng)對(duì)DOM發(fā)送改變的指令
div.style.color = 'red'

layoutEffect()

layoutEffect 緊隨 DOM 修改指令發(fā)出之后執(zhí)行,此時(shí)雖然 DOM 指令已經(jīng)發(fā)出,但是在瀏覽器的機(jī)制中,內(nèi)容繪制是一個(gè)異步的過(guò)程,這會(huì)兒繪制并沒(méi)有執(zhí)行。

因此在事件循環(huán)中,layoutEfect 被定義為類似于 Promise 的微任務(wù),在 DOM 指令修改之后,內(nèi)容繪制之前執(zhí)行。

后續(xù)影響

大家可以猜想一下,如果我們?cè)?layoutEffect 中直接去修改 state,會(huì)發(fā)生什么事情。

看看下面這個(gè)例子:

function Demo() {
  const [count, setCount] = useState(0)
  
  useLayoutEffect(() => {
    if (count == 0) {
      setCount(1)
    }
  }, [count])
  
    return (
    <div>
      <div>{count}</div>
      <button 
        onClick={() => setCount(0)}
      >
        reset 0
      </button>
    </div>
  )
}

我們?cè)?state 中聲明一個(gè)變量 count,初始值設(shè)置為 0,并定義 layoutEffect,其中的邏輯就是當(dāng) count == 0 時(shí),將 count 設(shè)置為 1。

添加一個(gè)按鈕,當(dāng)按鈕點(diǎn)擊時(shí),把 count 重新設(shè)置為 0。

大家思考一下,此時(shí),頁(yè)面上的顯示結(jié)果,會(huì)在 0 和 1 之間來(lái)回切換嗎?

答案是不會(huì)。

因?yàn)楫?dāng)我們執(zhí)行 layoutEffect 時(shí),UI 并沒(méi)有進(jìn)入事件循環(huán)的繪制流程,此時(shí)還處于 JS 邏輯的執(zhí)行過(guò)程中,那么這個(gè)時(shí)候執(zhí)行 setCount,整個(gè)邏輯會(huì)重新執(zhí)行,對(duì)于瀏覽器而言,JS 針對(duì)同一個(gè) UI 發(fā)出了兩條不同的指令,在瀏覽器的渲染機(jī)制中,也會(huì)發(fā)生收集行為,將這兩條指令進(jìn)行合并,最后只執(zhí)行一條。

// setCount(0)
div.innerHTML = 0

// setCount(1)
div.innerHTML = 1

如上例,當(dāng) setCount(0) 與 setCount(1)  執(zhí)行完之后,實(shí)際上是發(fā)出了兩條修改元素內(nèi)容的指令給到瀏覽器。

當(dāng)我們使用 useLayoutEffect 時(shí)他可能會(huì)覆蓋你想要執(zhí)行的渲染內(nèi)容,也有可能會(huì)阻塞你的正常渲染過(guò)程,因此我們?cè)谑褂盟鼤r(shí),需要精確把控他的執(zhí)行時(shí)機(jī),防止出現(xiàn)你不想看到的結(jié)果。

但是很明顯我們可以看到 layoutEffect 的執(zhí)行時(shí)機(jī)比 effect 更早。因此我們也可以在 layoutEffect 中,執(zhí)行一些輕量的,不直接影響 state 的邏輯。

責(zé)任編輯:姜華 來(lái)源: 這波能反殺
相關(guān)推薦

2023-12-25 15:40:55

React開(kāi)發(fā)

2023-11-26 18:02:00

ReactDOM

2023-12-13 13:31:00

useEffect對(duì)象瀏覽器

2025-05-12 01:33:00

異步函數(shù)Promise

2023-12-12 08:41:01

2022-09-13 08:51:26

Python性能優(yōu)化

2024-09-09 08:02:27

2017-08-03 12:50:49

Web圖片資源瀏覽器

2018-07-18 15:13:56

MCU代碼時(shí)間

2021-02-24 11:44:35

語(yǔ)言計(jì)算函數(shù)嵌入式系統(tǒng)

2024-07-03 13:51:02

SQL毛刺數(shù)據(jù)庫(kù)

2019-07-12 09:30:12

DashboardDockerDNS

2010-09-08 15:00:03

SQL語(yǔ)句執(zhí)行

2023-11-30 07:45:11

useEffectReact

2025-05-16 08:21:45

2023-12-22 08:46:15

useEffectVueMobx

2011-05-17 13:32:04

oracle

2022-12-13 08:36:42

D-SMARTOracle數(shù)據(jù)庫(kù)

2021-09-28 10:32:53

循環(huán)類型useEffect

2015-05-14 10:26:37

Objective-CSwift
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)