欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

前置知識

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

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

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

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

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

useEffect

commitBeforeMutationEffects

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

function commitBeforeMutationEffects() {
  while (nextEffect$1 !== null) {
    // 一系列的賦值操作省略,這里的flags應(yīng)取自對應(yīng)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)度有關(guān),我們看以下 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 團隊設(shè)計這一套機制的心智模型需要我們自己在不斷調(diào)試代碼和理解中慢慢去熟悉。

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

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

相關(guān)文章

  • React事件綁定的方式詳解

    React事件綁定的方式詳解

    react事件綁定時。this并不會指向當(dāng)前DOM元素。往往使用bind來改變this指向,今天通過本文給大家介紹React事件綁定的方式,感興趣的朋友
    2021-07-07
  • React+Antd+Redux實現(xiàn)待辦事件的方法

    React+Antd+Redux實現(xiàn)待辦事件的方法

    這篇文章主要介紹了React+Antd+Redux實現(xiàn)待辦事件的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • React獲取url后面參數(shù)的值示例代碼

    React獲取url后面參數(shù)的值示例代碼

    這篇文章主要介紹了React獲取url后面參數(shù)的值示例代碼,代碼簡單易懂,文末給大家補充介紹了react獲取URL中參數(shù)方法,需要的朋友可以參考下
    2022-12-12
  • React替換傳統(tǒng)拷貝方法的Immutable使用

    React替換傳統(tǒng)拷貝方法的Immutable使用

    Immutable.js出自Facebook,是最流行的不可變數(shù)據(jù)結(jié)構(gòu)的實現(xiàn)之一。它實現(xiàn)了完全的持久化數(shù)據(jù)結(jié)構(gòu),使用結(jié)構(gòu)共享。所有的更新操作都會返回新的值,但是在內(nèi)部結(jié)構(gòu)是共享的,來減少內(nèi)存占用
    2023-02-02
  • React?數(shù)據(jù)共享useContext的實現(xiàn)

    React?數(shù)據(jù)共享useContext的實現(xiàn)

    本文主要介紹了React?數(shù)據(jù)共享useContext的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • React 非父子組件傳參的實例代碼

    React 非父子組件傳參的實例代碼

    React 主要用于構(gòu)建UI,很多人認(rèn)為 React 是 MVC 中的 V(視圖)。本文給大家介紹React 非父子組件傳參的相關(guān)知識,感興趣的朋友跟隨一起看看吧
    2021-04-04
  • react 項目 中使用 Dllplugin 打包優(yōu)化技巧

    react 項目 中使用 Dllplugin 打包優(yōu)化技巧

    在用 Webpack 打包的時候,對于一些不經(jīng)常更新的第三方庫,比如 react,lodash,vue 我們希望能和自己的代碼分離開,這篇文章主要介紹了react 項目 中 使用 Dllplugin 打包優(yōu)化,需要的朋友可以參考下
    2023-01-01
  • React Native全面屏狀態(tài)欄和底部導(dǎo)航欄適配教程詳細(xì)講解

    React Native全面屏狀態(tài)欄和底部導(dǎo)航欄適配教程詳細(xì)講解

    最近在寫 React Native 項目,調(diào)試應(yīng)用時發(fā)現(xiàn)頂部狀態(tài)欄和底部全面屏手勢指示條區(qū)域不是透明的,看起來很難受。研究了一下這個問題,現(xiàn)在總結(jié)一下解決方案,這篇文章主要介紹了React Native全面屏狀態(tài)欄和底部導(dǎo)航欄適配教程
    2023-01-01
  • react 下拉框內(nèi)容回顯的實現(xiàn)思路

    react 下拉框內(nèi)容回顯的實現(xiàn)思路

    這篇文章主要介紹了react 下拉框內(nèi)容回顯,實現(xiàn)思路是通過將下拉框選項的value和label一起存儲到state中, 初始化表單數(shù)據(jù)時將faqType對應(yīng)的label查找出來并設(shè)置到Form.Item中,最后修改useEffect,需要的朋友可以參考下
    2024-05-05
  • 使用react-color實現(xiàn)前端取色器的方法

    使用react-color實現(xiàn)前端取色器的方法

    本文通過代碼給大家介紹了使用react-color實現(xiàn)前端取色器的方法,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-11-11

最新評論