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

一文掌握React?組件樹遍歷技巧

 更新時(shí)間:2023年04月17日 09:56:07   作者:uccs  
這篇文章主要為大家介紹了React?組件樹遍歷技巧的掌握,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

本文對應(yīng)的 react 版本是 18.2.0

下面的 dom 結(jié)構(gòu)react 內(nèi)部是如何遍歷的

const App = () => {
  return (
    <div>
      <button>+1</button>
      <A count={0} />
    </div>
  );
};
const A = (props) => {
  useEffect(() => {
    console.log(props.count);
  }, [props.count]);
  return <div>{props.count}</div>;
};

react 內(nèi)部遍歷核心邏輯:

  • render 時(shí)調(diào)用 commitPassiveUnmountOnFiber 函數(shù)
  • commitPassiveUnmountOnFiber 處理不同的 WorkTag,并調(diào)用 recursivelyTraversePassiveUnmountEffects
  • recursivelyTraversePassiveUnmountEffects 根據(jù)當(dāng)前 Fiber 的子節(jié)點(diǎn)有沒有 passive effectuseEffect,useLayoutEffect)來決定是否遍歷當(dāng)前 Fiber 的子節(jié)點(diǎn)
    • 如果子節(jié)點(diǎn)有 passive effect,則優(yōu)先遍歷子節(jié)點(diǎn) (深度優(yōu)先),直到找到最終的葉子節(jié)點(diǎn),退出當(dāng)前循環(huán)
    • 然后進(jìn)入兄弟節(jié)點(diǎn),開始遍歷兄弟節(jié)點(diǎn)的子節(jié)點(diǎn)
      • 具體從哪個(gè)兄弟節(jié)點(diǎn)開始遍歷,react 選擇的是離退出循環(huán)的那個(gè)葉子節(jié)點(diǎn)的父節(jié)點(diǎn),檢查有沒有子節(jié)點(diǎn),以此循環(huán)遍歷
    • 直到最后找到所有有 passive effect 的節(jié)點(diǎn)

代碼簡化:

commitPassiveUnmountOnFiber(root.current);
function commitPassiveUnmountOnFiber(finishedWork) {
  // 省略了處理不同的 WorkTag
  recursivelyTraversePassiveUnmountEffects(finishedWork);
}
function recursivelyTraversePassiveUnmountEffects(parentFiber) {
  // 省略了其他處理
  if (parentFiber.subtreeFlags & PassiveMask) {
    let child = parentFiber.child;
    while (child !== null) {
      commitPassiveUnmountOnFiber(child);
      child = child.sibling;
    }
  }
}

所以對于這段 dom 的遍歷邏輯是:

  • 首先從根組件開始 FiberRootNode,取到 current
    • 也就是說 FiberRootNode.currentdiv#root 這是一個(gè) fiber,它的 tag3
  • 由于 App 的子組件有 passive effect,所以會(huì)進(jìn)入 App 組件,它的 tag0
  • App 組件中節(jié)點(diǎn)是 <div>,<di >tag5
    • <div> 下面有兩個(gè)子元素 <button>、<A>
  • 先遍歷 <button> 它的 tag5
  • <button> 內(nèi)部只有一個(gè)文本節(jié)點(diǎn),沒有 passive effect
    • 所以 react 不遍歷了(跳出當(dāng)前遍歷的循環(huán),也就是 button 這條不在遍歷了)
  • 跳出循環(huán)后,查看 button 的兄弟節(jié)點(diǎn),它的兄弟節(jié)點(diǎn)是 <A>,<A>tag0
  • 由于 <A> 節(jié)點(diǎn)的子節(jié)點(diǎn)沒有 passive effect,所以跳出循環(huán),結(jié)束整個(gè)遍歷

總結(jié)

  • 從跟節(jié)點(diǎn)開始遍歷
  • 當(dāng)前組件的子組件有沒有 passive effect
  • 采取深度優(yōu)先
  • 如果 dom 節(jié)點(diǎn)內(nèi)有函數(shù)組件,則這個(gè) dom 會(huì)被遍歷,否則不會(huì)遍歷
  • 如果當(dāng)前 fiber 下的所有子 fiber 都沒有 passive effect ,則這一整個(gè)都鏈表都不會(huì)被遍歷
  • 如果當(dāng)前 fiber 只有 dom,則這些 dom 也不會(huì)遍歷

總的來說組件會(huì)不會(huì)別遍歷看 fiber 有沒有 passive effect

  • 有,一定會(huì)被遍歷
  • 沒有,下面兩種情況會(huì)被遍歷,其他情況不會(huì)被遍歷
    • passive effect 的父組件
    • passive effect 組件是兄弟組件

passive effect 指的是 useEffectuseLayoutEffect

遍歷邏輯如下圖所示

圖中畫綠色勾的都會(huì)被遍歷,紅色勾是遍歷的順序

以上就是一文掌握React 組件樹遍歷技巧的詳細(xì)內(nèi)容,更多關(guān)于React 組件樹遍歷的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • react-router-domV6版本改版踩坑記錄

    react-router-domV6版本改版踩坑記錄

    這篇文章主要介紹了react-router-domV6版本改版踩坑記錄,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 淺談redux以及react-redux簡單實(shí)現(xiàn)

    淺談redux以及react-redux簡單實(shí)現(xiàn)

    這篇文章主要介紹了淺談redux以及react-redux簡單實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-08-08
  • React函數(shù)組件傳參的實(shí)現(xiàn)

    React函數(shù)組件傳參的實(shí)現(xiàn)

    React函數(shù)組件通過接受props實(shí)現(xiàn)組件間的數(shù)據(jù)傳遞,通過組件標(biāo)簽的屬性向子組件傳遞數(shù)據(jù),并在子組件中通過參數(shù)接收,還可以使用ES6的解構(gòu)賦值,函數(shù)也能作為props傳遞,以實(shí)現(xiàn)父子組件間的交互和通信,下面就來具體了解一下
    2024-09-09
  • React Diff原理深入分析

    React Diff原理深入分析

    這篇文章主要介紹了React Diff原理的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用React框架,感興趣的朋友可以了解下
    2021-04-04
  • react路由配置方式詳解

    react路由配置方式詳解

    本篇文章主要介紹了react路由配置方式詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • 淺談React和Redux的連接react-redux

    淺談React和Redux的連接react-redux

    本篇文章主要介紹了淺談React和Redux的連接react-redux,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-12-12
  • React狀態(tài)提升案例介紹

    React狀態(tài)提升案例介紹

    這篇文章主要介紹了React狀態(tài)提升案例,所謂 狀態(tài)提升 就是將各個(gè)子組件的 公共state 提升到它們的父組件進(jìn)行統(tǒng)一存儲(chǔ)、處理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-04-04
  • React事件監(jiān)聽和State狀態(tài)修改方式

    React事件監(jiān)聽和State狀態(tài)修改方式

    這篇文章主要介紹了React事件監(jiān)聽和State狀態(tài)修改方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • React實(shí)現(xiàn)翻頁時(shí)鐘的代碼示例

    React實(shí)現(xiàn)翻頁時(shí)鐘的代碼示例

    本文給大家介紹了React實(shí)現(xiàn)翻頁時(shí)鐘的代碼示例,翻頁時(shí)鐘把數(shù)字分為上下兩部分,翻頁效果的實(shí)現(xiàn)需要通過設(shè)置 position 把所有的數(shù)組放在同一個(gè)位置疊加起來,文中有詳細(xì)的代碼講解,需要的朋友可以參考下
    2023-08-08
  • 對react中間件的理解

    對react中間件的理解

    這篇文章主要介紹了對react中間件的理解,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11

最新評(píng)論

耿马| 富川| 伊川县| 庆阳市| 肃北| 大同市| 隆安县| 崇阳县| 清水河县| 乐平市| 类乌齐县| 泗阳县| 中牟县| 松潘县| 无极县| 仁化县| 西青区| 酉阳| 阳信县| 利川市| 郁南县| 井冈山市| 大名县| 于都县| 舒城县| 华安县| 仁怀市| 绥中县| 宝兴县| 新民市| 大埔区| 永定县| 石嘴山市| 崇义县| 苍溪县| 江安县| 乌鲁木齐市| 舒城县| 洪江市| 曲阳县| 通辽市|