最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React中useEffect 與 useLayoutEffect的區(qū)別

 更新時間:2021年07月25日 16:26:25   作者:Alander  
本文主要介紹了React中useEffect與useLayoutEffect的區(qū)別,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前置知識

我們可以將 React 的工作流程劃分為幾大塊:

  1. render 階段:主要生成 Fiber節(jié)點 并構(gòu)建出完整的 Fiber樹
  2. commit 階段:在上一個render 階段中會在 rootFiber 上生成一條副作用鏈表,應用的DOM操作就會在本階段執(zhí)行

commit階段的工作主要分為三部分,對應到源碼中的函數(shù)名是:

  • commitBeforeMutationEffects階段:主要處理執(zhí)行DOM操作前的一些相關操作
  • commitMutationEffects階段:執(zhí)行DOM操作
  • commitLayoutEffects階段:主要處理執(zhí)行DOM操作后的一些相關操作

useEffect 和 useLayoutEffect 的區(qū)別主要就在體現(xiàn)在這三個階段的處理上。結(jié)論是:useEffect 會異步地去執(zhí)行它的響應函數(shù)和上一次的銷毀函數(shù),而useLayoutEffect 會同步地執(zhí)行它的響應函數(shù)和上一次的銷毀函數(shù),即會阻塞住 DOM渲染。

useEffect

commitBeforeMutationEffects

在這個階段中 useEffect 著重會經(jīng)歷一句話如下:

function commitBeforeMutationEffects() {
  while (nextEffect$1 !== null) {
    // 一系列的賦值操作省略,這里的flags應取自對應FunctionComponent的effect的flags,具體實現(xiàn)請看源碼
    var flags = effect.flags;

  // 處理生命周期
    if ((flags & Snapshot) !== NoFlags) {
      setCurrentFiber(nextEffect$1);
      commitBeforeMutationLifeCycles(current, nextEffect$1);
      resetCurrentFiber();
    }

 // 這個if判斷只有 useEffect 為 true,useLayoutEffect 為false
    if ((flags & Passive) !== NoFlags) {
      // If there are passive effects, schedule a callback to flush at
      // the earliest opportunity.
      if (!rootDoesHavePassiveEffects) {
        rootDoesHavePassiveEffects = true;
 // 這里就是 useEffect 異步的原因,DOM操作后React會調(diào)度 flushPassiveEffects
        scheduleCallback(NormalPriority, function () {
          flushPassiveEffects();
          return null;
        });
      }
    }

    nextEffect$1 = nextEffect$1.nextEffect;
  }
}

commitMutationEffects

在這個階段中,React 會進行一系列的DOM節(jié)點更新 ,然后會執(zhí)行一個方法: commitHookEffectListUnmount(HookLayout | HookHasEffect, finishedWork);

那么一個擁有 useEffect 的 Functional Component 在這個階段是不符合 unmount 的判斷邏輯的,所以在這個地方不會做 unmount 操作。

commitLayoutEffects

在這個階段中,依然有一個很重要的方法存在:commitHookEffectListMount(HookLayout | HookHasEffect, finishedWork);

這個if判斷和上一階段的if判斷是一樣的,useEffec 在這個判斷中不會做任何操作。

后續(xù)階段

在完成了 commitLayoutEffects 后,還有一個操作:

if (rootDoesHavePassiveEffects) {
    // This commit has passive effects. Stash a reference to them. But don't
    // schedule a callback until after flushing layout work.
    rootDoesHavePassiveEffects = false;
    rootWithPendingPassiveEffects = root;
    pendingPassiveEffectsLanes = lanes;
    pendingPassiveEffectsRenderPriority = renderPriorityLevel;
  }

即把 rootWithPendingPassiveEffects 置為 root ,這么做的原因和第一階段 commitBeforeMutationEffects 中 useEffect 注冊的下一次 flushPassiveEffects 異步調(diào)度有關,我們看以下 flushPassiveEffects 的實現(xiàn):

function flushPassiveEffectsImpl() {
 if (rootWithPendingPassiveEffects === null) {
    return false;
  }
 // 省略一系列的性能追蹤等操作
 commitPassiveUnmountEffects(root.current);
  commitPassiveMountEffects(root, root.current);
}


從上述代碼段可以看見,useEffect 在第一階段注冊的調(diào)度回調(diào)會在頁面更新后進行 unmount 和 mount 操作。值得一提的是,這個回調(diào)中effect的注冊時機就是在 commitLayoutEffects 階段。

useLayoutEffect

其實根據(jù)我們對 useEffect 的解析來看,就是在 commitMutationEffects 和 commitLayoutEffects 階段中各自的 if 判斷中,useLayoutEffect 是通過if判斷的,所以在 commitMutationEffects 階段中,同步執(zhí)行了useLayoutEffect 的上一次銷毀函數(shù),在 commitLayoutEffects 階段中,同步執(zhí)行了 useLayoutEffect 本次的執(zhí)行函數(shù),并注冊上銷毀函數(shù)。

結(jié)論

至此,我們粗略地查看了 commit 階段的代碼,分析了以下為什么 useEffect 是異步執(zhí)行,而 useLayoutEffect 是同步執(zhí)行,具體的代碼我沒有太過在文章中貼出來,因為這些都是可變的,真正的流程性的概覽和 React 團隊設計這一套機制的心智模型需要我們自己在不斷調(diào)試代碼和理解中慢慢去熟悉。

后續(xù)自己感興趣的是 hooks 的實現(xiàn),其中比較關鍵的 useReducer 會著重看一下源碼,看看能不能寫個簡易版本的放到支付寶小程序中去實現(xiàn)一個 自定義的支付寶hooks 用于日常生產(chǎn)力開發(fā)。

到此這篇關于React中useEffect 與 useLayoutEffect的區(qū)別的文章就介紹到這了,更多相關React useEffect useLayoutEffect內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 深入理解React合成事件

    深入理解React合成事件

    React的合成事件是一個跨瀏覽器統(tǒng)一的事件系統(tǒng),它基于原生DOM事件構(gòu)建,通過封裝不同瀏覽器的事件實現(xiàn)差異,為開發(fā)者提供一致的事件處理接口,具有一定的參考價值,感興趣的可以了解一下
    2026-01-01
  • react路由v6版本NavLink的兩個小坑及解決

    react路由v6版本NavLink的兩個小坑及解決

    這篇文章主要介紹了react路由v6版本NavLink的兩個小坑及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • React中組件的this.state和setState的區(qū)別

    React中組件的this.state和setState的區(qū)別

    在React開發(fā)中,this.state用于初始化和讀取組件狀態(tài),而setState()用于安全地更新狀態(tài),正確使用這兩者對于管理React組件狀態(tài)至關重要,避免性能問題和常見錯誤
    2024-09-09
  • React八大常見錯誤及其解決方案

    React八大常見錯誤及其解決方案

    這篇文章主要介紹了React八大常見錯誤及其解決方案,并通過代碼示例介紹的非常詳細,對大家學習react有一定的幫助,感興趣的朋友可以參考下
    2024-03-03
  • react navigation中點擊底部tab怎么傳遞參數(shù)

    react navigation中點擊底部tab怎么傳遞參數(shù)

    本文主要介紹了react navigation中點擊底部tab怎么傳遞參數(shù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • React中如何設置自定義滾動條樣式

    React中如何設置自定義滾動條樣式

    這篇文章主要介紹了React中如何設置自定義滾動條樣式問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • React實現(xiàn)模糊搜索和關鍵字高亮的示例代碼

    React實現(xiàn)模糊搜索和關鍵字高亮的示例代碼

    這篇文章主要為大家詳細介紹了React如何實現(xiàn)模糊搜索和關鍵字高亮的效果,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-11-11
  • React團隊測試并發(fā)特性詳解

    React團隊測試并發(fā)特性詳解

    這篇文章主要為大家介紹了React團隊測試并發(fā)特性詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • React?中使用?RxJS?優(yōu)化數(shù)據(jù)流的處理方案

    React?中使用?RxJS?優(yōu)化數(shù)據(jù)流的處理方案

    這篇文章主要為大家介紹了React?中使用?RxJS?優(yōu)化數(shù)據(jù)流的處理方案示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • react執(zhí)行【npx create-react-app my-app】出現(xiàn)常見錯誤的解決辦法

    react執(zhí)行【npx create-react-app my-app】出現(xiàn)常見錯誤的解決辦法

    文章主要介紹了在使用npx創(chuàng)建React應用時可能遇到的幾種常見錯誤及其解決方法,包括缺少依賴、網(wǎng)絡問題和npx解析錯誤等,并提供了相應的解決措施,此外,還提到了使用騰訊云云產(chǎn)品來支持React應用開發(fā)
    2024-11-11

最新評論

益阳市| 松潘县| 安丘市| 阿坝县| 随州市| 宝应县| 普兰店市| 蓬莱市| 凤阳县| 厦门市| 阿拉善盟| 河东区| 吴旗县| 江北区| 定边县| 绍兴县| 涞源县| 贺州市| 东海县| 盈江县| 长葛市| 壶关县| 封丘县| 花莲县| 醴陵市| 肃宁县| 尉氏县| 洛南县| 余江县| 岳普湖县| 内乡县| 高陵县| 阿拉善盟| 东平县| 宁南县| 昌吉市| 福清市| 开阳县| 和硕县| 滦南县| 彩票|