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

簡單分析React中的EffectList

 更新時間:2021年04月07日 10:15:28   作者:zhangyu  
這篇文章主要簡單分析了React中的EffectList,幫助大家更好的理解和學習使用React進行前端開發(fā),感興趣的朋友可以了解下

React中,會遍歷EffectList來執(zhí)行節(jié)點操作、生命周期方法、Effect方法,可以把EffectList比作圣誕樹上掛的彩燈,而這顆圣誕樹就是Fiber樹。

為什么會存在EffectList呢?打個比方來說,一顆Fiber樹中有一些Fiber節(jié)點需要執(zhí)行componentDidMount方法,如果在Fiber樹構建完成后,再遍歷一次Fiber樹,找到需要執(zhí)行componentDidMount方法的Fiber節(jié)點,這是非常低效的。

而EffectList就解決了這個問題,在Fiber樹構建過程中,每當一個Fiber節(jié)點的flags字段不為NoFlags時(代表需要執(zhí)行副作用),就把該Fiber節(jié)點添加到EffectList,在Fiber樹構建完成后,由Fiber節(jié)點串成的彩燈也構建完成了,這樣僅僅需要遍歷彩燈就行了。

EffectList的收集

EffectList是一個單向鏈表,firstEffect代表鏈表中的第一個Fiber節(jié)點,lastEffect代表鏈表中的最后一個Fiber節(jié)點。

Fiber樹的構建是深度優(yōu)先的,也就是先向下構建子級Fiber節(jié)點,子級節(jié)點構建完成后,再向上構建父級Fiber節(jié)點,所以EffectList中總是子級Fiber節(jié)點在前面。

Fiber節(jié)點構建完成的操作執(zhí)行在completeUnitOfWork方法,在這個方法里,不僅會對節(jié)點完成構建,也會將有flags的Fiber節(jié)點添加到EffectList。

簡化代碼如下。

function completeUnitOfWork(unitOfWork: Fiber): void {
 let completedWork = unitOfWork;
 do {
  const current = completedWork.alternate;
  const returnFiber = completedWork.return;
  
  let next= completeWork(current, completedWork, subtreeRenderLanes);

  // effect list構建
  if (
   returnFiber !== null &&
   (returnFiber.flags & Incomplete) === NoFlags
  ) {
   // 層層拷貝
   if (returnFiber.firstEffect === null) {
    returnFiber.firstEffect = completedWork.firstEffect;
   }
   if (completedWork.lastEffect !== null) {
    // 說明當前節(jié)點是兄弟節(jié)點,子節(jié)點有effect,已經(jīng)給returnFiber.lastEffect賦值過了
    if (returnFiber.lastEffect !== null) {
     // 連接兄弟節(jié)點的effect
     returnFiber.lastEffect.nextEffect = completedWork.firstEffect;
    }
    returnFiber.lastEffect = completedWork.lastEffect;
   }
   
   const flags = completedWork.flags;
   
   // 該fiber節(jié)點有effect
   if (flags > PerformedWork) {
    // 當前節(jié)點有effect連接上effect list
    if (returnFiber.lastEffect !== null) {
     returnFiber.lastEffect.nextEffect = completedWork;
    } else {
     // returnFiber沒有firstEffect的情況是第一次遇見有effect的節(jié)點
     returnFiber.firstEffect = completedWork;
    }
    returnFiber.lastEffect = completedWork;
   }
  }

  // 兄弟元素遍歷再到返返回父級
  const siblingFiber = completedWork.sibling;
  if (siblingFiber !== null) {
   workInProgress = siblingFiber;
   return;
  }
  completedWork = returnFiber;
  workInProgress = completedWork;
 } while (completedWork !== null);
}

EffectList實際是像冒泡一樣,一層一層不斷向上層收集,從第一個有flags的節(jié)點開始記錄,每層的新節(jié)點都會將上一個節(jié)點的firstEffectlastEffect拷貝到自身身上,再供上層節(jié)點再次拷貝。

如以下結構,假如每一個div都有flags

<div id="1">
 <div id="4"/>
 <div id="2">
  <div id="3"/>
 </div>
</div>

最終形成的EffectList為

firstEffect => div4
lastEffect => div1

因為Fiber樹的構建深度優(yōu)先,所有div4先完成completeWork,構建firstEffect。

EffectList遍歷是從firstEffect開始,通過每一個節(jié)點的nextEffect找到下一個節(jié)點。

firstEffect => div4
div4.nextEffect => div3
div3.nextEffect => div2
div2.nextEffect => div1

初次Render時的EffectList

在React中,會對初次Mount有一個性能優(yōu)化,其中的Fiber節(jié)點的flags不會包含placement,對應的DOM節(jié)點不會遍歷加入DOM樹,而是在創(chuàng)建DOM節(jié)點時就已經(jīng)加入DOM樹了,只有rootFiber節(jié)點FiberRootNodeflags會包含placement。

EffectList是不會包含root節(jié)點的,所以需要將root節(jié)點也添加到EffectList,這樣才會正確的執(zhí)行placement,讓DOM樹在頁面呈現(xiàn) 。

 let firstEffect;
 // 把根節(jié)點finishedWork也連接進去
 if (finishedWork.flags > PerformedWork) {
  if (finishedWork.lastEffect !== null) {
   finishedWork.lastEffect.nextEffect = finishedWork;
   firstEffect = finishedWork.firstEffect;
  } else {
   firstEffect = finishedWork;
  }
 } else {
  // 根節(jié)點沒有effect.
  firstEffect = finishedWork.firstEffect;
 }

EffectList的遍歷

EffectList的主要是用于Layout階段生命周期方法的執(zhí)行和DOM的操作。

// 處理getSnapshotBeforeUpdate,調(diào)度useEffect
nextEffect = firstEffect;
do {
 commitBeforeMutationEffects();
} while (nextEffect !== null);
// DOM操作
nextEffect = firstEffect;
do {
 commitMutationEffects(root, renderPriorityLevel);
} while (nextEffect !== null);
// 生命周期方法的執(zhí)行
nextEffect = firstEffect;
do {
 commitLayoutEffects(root, lanes);
} while (nextEffect !== null);

在這Layout階段的這3個方法里,會遍歷nextEffect,每執(zhí)行完一個,就重新指向firstEffect。Layout階段具體操作就不細講了。

總結

EffectList不是全局變量,只是在Fiber樹創(chuàng)建過程中,一層層向上收集有effect的Fiber節(jié)點,最終的root節(jié)點就會收集到所有有effect到Fiber節(jié)點,我們就把這條包含effect節(jié)點的鏈表叫做EffectList。

由于收集的過程是深度優(yōu)先,子級會先被收集,所以遍歷的時候也會先操作子級,所以如果有面試官問子級和父級的生命周期或者useEffect誰先執(zhí)行,就很清楚的知道會先執(zhí)行子級操作了。

以上就是簡單分析React中的EffectList的詳細內(nèi)容,更多關于React中的EffectList的資料請關注腳本之家其它相關文章!

相關文章

  • React 父子組件通信的實現(xiàn)方法

    React 父子組件通信的實現(xiàn)方法

    這篇文章主要介紹了React 父子組件通信的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-12-12
  • 詳解如何在React函數(shù)式組件中使用MobX

    詳解如何在React函數(shù)式組件中使用MobX

    MobX 是一個簡潔的狀態(tài)管理庫,它通過透明的函數(shù)響應式編程(TFRP)使得狀態(tài)管理變得簡單和可擴展,下面就跟隨小編一起來了解一下如何在React函數(shù)式組件中使用MobX吧
    2024-01-01
  • React Native自定義組件與輸出方法詳解

    React Native自定義組件與輸出方法詳解

    這篇文章主要給大家介紹了關于React Native自定義組件與輸出方法的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-07-07
  • react中通過props實現(xiàn)父子組件間通信的使用示例

    react中通過props實現(xiàn)父子組件間通信的使用示例

    在React中,父組件可以通過props屬性向子組件傳遞數(shù)據(jù),子組件可以通過props屬性接收父組件傳遞過來的數(shù)據(jù),本文就來介紹一下如何實現(xiàn),感興趣的可以了解一下
    2023-10-10
  • 使用react render props實現(xiàn)倒計時的示例代碼

    使用react render props實現(xiàn)倒計時的示例代碼

    這篇文章主要介紹了使用react render props實現(xiàn)倒計時的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • react中context傳值和生命周期詳解

    react中context傳值和生命周期詳解

    這篇文章主要介紹了react中context傳值和生命周期,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • React中useState原理的代碼簡單實現(xiàn)

    React中useState原理的代碼簡單實現(xiàn)

    要實現(xiàn)useState的背后原理,則需要深入了解狀態(tài)是如何在函數(shù)組件的渲染周期中保持和更新的,本文將通過一段代碼簡單闡述useState鉤子函數(shù)的實現(xiàn)思路,希望對大家有所幫助
    2023-12-12
  • React中代碼分割的4種實現(xiàn)方式

    React中代碼分割的4種實現(xiàn)方式

    雖然一直有做react相關的優(yōu)化,按需加載、dll 分離、服務端渲染,但是從來沒有從路由代碼分割這一塊入手過,所以下面這篇文章主要給大家介紹了關于React中代碼分割的4種實現(xiàn)方式,需要的朋友可以參考下
    2022-01-01
  • React 中的 useContext使用方法

    React 中的 useContext使用方法

    這篇文章主要介紹了React中的useContext使用,使用useContext在改變一個數(shù)據(jù)時,是通過自己逐級查找對比改變的數(shù)據(jù)然后渲染,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • React中useEffect函數(shù)的使用詳解

    React中useEffect函數(shù)的使用詳解

    useEffect是React中的一個鉤子函數(shù),用于處理副作用操作,這篇文章主要為大家介紹了React中useEffect函數(shù)的具體用法,希望對大家有所幫助
    2023-08-08

最新評論

平乐县| 澄迈县| 介休市| 新化县| 德钦县| 韩城市| 黔南| 云和县| 丰县| 满城县| 乐亭县| 蓝田县| 三都| 鄂伦春自治旗| 乐至县| 余干县| 新宾| 阳山县| 新田县| 民权县| 辉县市| 修武县| 汤阴县| 富蕴县| 仁化县| 大化| 马山县| 朝阳县| 永城市| 长武县| 吕梁市| 十堰市| 莱阳市| 南华县| 高碑店市| 红原县| 南岸区| 嵩明县| 酉阳| 门源| 冷水江市|