成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

React 源碼深度解讀(三):首次 DOM 元素渲染 - Part 3

U2FsdGVkX1x / 1096人閱讀

摘要:在學(xué)習(xí)源碼的過程中,給我?guī)椭畲蟮木褪沁@個系列文章,于是決定基于這個系列文章談一下自己的理解。到此為止,首次渲染就完成啦總結(jié)從啟動到元素渲染到頁面,并不像看起來這么簡單,中間經(jīng)歷了復(fù)雜的層級調(diào)用。

前言

React 是一個十分龐大的庫,由于要同時考慮 ReactDom 和 ReactNative ,還有服務(wù)器渲染等,導(dǎo)致其代碼抽象化程度很高,嵌套層級非常深,閱讀其源碼是一個非常艱辛的過程。在學(xué)習(xí) React 源碼的過程中,給我?guī)椭畲蟮木褪沁@個系列文章,于是決定基于這個系列文章談一下自己的理解。本文會大量用到原文中的例子,想體會原汁原味的感覺,推薦閱讀原文。

本系列文章基于 React 15.4.2 ,以下是本系列其它文章的傳送門:
React 源碼深度解讀(一):首次 DOM 元素渲染 - Part 1
React 源碼深度解讀(二):首次 DOM 元素渲染 - Part 2
React 源碼深度解讀(三):首次 DOM 元素渲染 - Part 3
React 源碼深度解讀(四):首次自定義組件渲染 - Part 1
React 源碼深度解讀(五):首次自定義組件渲染 - Part 2
React 源碼深度解讀(六):依賴注入
React 源碼深度解讀(七):事務(wù) - Part 1
React 源碼深度解讀(八):事務(wù) - Part 2
React 源碼深度解讀(九):單個元素更新
React 源碼深度解讀(十):Diff 算法詳解

正文

上一篇講解了平臺無關(guān)的代碼,這篇繼續(xù)來講針對與 HTML DOM 操作的代碼。

|=ReactMount.render(nextElement, container, callback)     ___
|=ReactMount._renderSubtreeIntoContainer()                 |
  |-ReactMount._renderNewRootComponent()                   |
    |-instantiateReactComponent()                          |
    |~batchedMountComponentIntoNode()                  upper half
      |~mountComponentIntoNode()                       (平臺無關(guān))
        |-ReactReconciler.mountComponent()                 |
          |-ReactCompositeComponent.mountComponent()       |
          |-ReactCompositeComponent.performInitialMount()  |
            |-instantiateReactComponent()                 _|_
            |-ReactDOMComponent.mountComponent()       lower half
        |-_mountImageIntoNode()                      (HTML DOM 相關(guān))
                                                          _|_

先來看看 ReactDOMComponent.mountComponent 做了什么:

// 文件位置:src/renderers/dom/shared/ReactDomComponent.js

tComponent: function (
    transaction,
    hostParent,
    hostContainerInfo,
    context
) {
    ...

    var mountImage;
    
    var ownerDocument = hostContainerInfo._ownerDocument;
    var el;
    
    // document.createElement 創(chuàng)建 h1 元素
    el = ownerDocument.createElement(this._currentElement
                .type, props.is);

    ...
  
    // 創(chuàng)建 component 與 DOM 的雙向鏈接
    // ReactDOMComponent[ins]._hostNode 指向 DOM
    // DOM 的 __reactInternalInstance 指向 component
    ReactDOMComponentTree.precacheNode(this, el);
    
    // 設(shè)置屬性
    this._updateDOMProperties(null, props, transaction);
    
    var lazyTree = DOMLazyTree(el);
    
    // 循環(huán)創(chuàng)建子元素
    this._createInitialChildren(transaction, props, context,
        lazyTree);
        
    mountImage = lazyTree;

    ...

    return mountImage;
},

到此為止,實例間的關(guān)系是這樣的:

DOM 元素創(chuàng)建完成后,剩下的就是將其掛載到 container 上面去了。這里調(diào)用的是 ReactMount 的 _mountImageIntoNode:

|=ReactMount.render(nextElement, container, callback)     ___
|=ReactMount._renderSubtreeIntoContainer()                 |
  |-ReactMount._renderNewRootComponent()                   |
    |-instantiateReactComponent()                          |
    |~batchedMountComponentIntoNode()                  upper half
      |~mountComponentIntoNode(                        (平臺無關(guān))
          wrapperInstance, // scr: -> not of interest now  |
          container,   // scr: --> document.getElementById(‘root’)
          transaction, // scr: --> not of interest         |
          shouldReuseMarkup, // scr: -------> null         |
          context,           // scr: -------> not of interest
        )                                                  |
        |-ReactReconciler.mountComponent()                 |
          |-ReactCompositeComponent.mountComponent()       |
          |-ReactCompositeComponent.performInitialMount()  |
            |-instantiateReactComponent()                 _|_
            |-ReactDOMComponent.mountComponent()           |
       /* we are here */                               lower half
        |-_mountImageIntoNode()                      (HTML DOM 相關(guān))
            markup,    // scr: --> DOMLazyTree[ins]        |
            container, // scr: --> document.getElementById(‘root’)
            wrapperInstance, // scr:----> same             |
            shouldReuseMarkup, // scr:--> same             |
            transaction, // scr: -------> same             |
          )    

具體實現(xiàn):

_mountImageIntoNode: function (
        markup,        // DOMLazyTree[ins] 
        container,     // document.getElementById(‘root’)
        instance,
        shouldReuseMarkup,
        transaction
    ) {
        ...
        
        while (container.lastChild) {
            container.removeChild(container.lastChild);
        }
        
        DOMLazyTree.insertTreeBefore(container, markup, null);

        ...
    }

DOMLazyTree.insertTreeBefore 最終會調(diào)用 parentNode.insertBefore,將元素掛載到 container 上。到此為止,首次渲染就完成啦!

總結(jié)

從 React 啟動到元素渲染到頁面,并不像看起來這么簡單,中間經(jīng)歷了復(fù)雜的層級調(diào)用。原文的這張圖總結(jié)得非常好:

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/98522.html

相關(guān)文章

  • React 源碼深度解讀(四):首次自定義組件渲染 - Part 1

    摘要:本篇開始介紹自定義組件是如何渲染的。組件將自定義組件命名為,結(jié)構(gòu)如下經(jīng)過編譯后,生成如下代碼構(gòu)建頂層包裝組件跟普通元素渲染一樣,第一步先會執(zhí)行創(chuàng)建為的。調(diào)用順序已在代碼中注釋。先看圖,這部分內(nèi)容將在下回分解 前言 React 是一個十分龐大的庫,由于要同時考慮 ReactDom 和 ReactNative ,還有服務(wù)器渲染等,導(dǎo)致其代碼抽象化程度很高,嵌套層級非常深,閱讀其源碼是一個非...

    Warren 評論0 收藏0
  • React 源碼深度解讀(一):首次DOM元素渲染 - Part 1

    摘要:調(diào)用棧是這樣的這里生成的我們將其命名為,它將作為參數(shù)傳入到。整個的調(diào)用棧是這樣的組件間的層級結(jié)構(gòu)是這樣的到此為止,頂層對象已經(jīng)構(gòu)造完畢,下一步就是調(diào)用來自的方法,進(jìn)行頁面的渲染了。通過表達(dá)的結(jié)構(gòu)最終會轉(zhuǎn)化為一個純對象,用于下一步的渲染。 歡迎關(guān)注我的公眾號睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言...

    daydream 評論0 收藏0
  • React 源碼深度解讀(二):首次 DOM 元素渲染 - Part 2

    摘要:本文將要講解的調(diào)用棧是下面這個樣子的平臺無關(guān)相關(guān)如果看源碼,我們會留意到很多相關(guān)的代碼,我們暫時先將其忽略,會在后續(xù)的文章中進(jìn)行講解。現(xiàn)在我們來看一下各實例間的關(guān)系目前為止的調(diào)用棧平臺無關(guān)相關(guān)下一篇講解三總結(jié)本文講解了轉(zhuǎn)化為的過程。 歡迎關(guān)注我的公眾號睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言 R...

    wean 評論0 收藏0
  • React 源碼深度解讀(五):首次自定義組件渲染 - Part 2

    摘要:的和真正有效的都各只有一行代碼的調(diào)用棧如下這中間的函數(shù)調(diào)用邏輯很清晰,最終會走到這里這里的邏輯很簡單,如果不是數(shù)組,則調(diào)用回調(diào)函數(shù)如果是數(shù)組,則繼續(xù)調(diào)用自身,相當(dāng)于深度優(yōu)先遍歷。這里的回調(diào)函數(shù)就是中的這里直接調(diào)用,創(chuàng)建。 前言 React 是一個十分龐大的庫,由于要同時考慮 ReactDom 和 ReactNative ,還有服務(wù)器渲染等,導(dǎo)致其代碼抽象化程度很高,嵌套層級非常深,閱讀...

    william 評論0 收藏0
  • React 源碼深度解讀(八):事務(wù) - Part 2

    摘要:前言是一個十分龐大的庫,由于要同時考慮和,還有服務(wù)器渲染等,導(dǎo)致其代碼抽象化程度很高,嵌套層級非常深,閱讀其源碼是一個非常艱辛的過程。在學(xué)習(xí)源碼的過程中,給我?guī)椭畲蟮木褪沁@個系列文章,于是決定基于這個系列文章談一下自己的理解。 前言 React 是一個十分龐大的庫,由于要同時考慮 ReactDom 和 ReactNative ,還有服務(wù)器渲染等,導(dǎo)致其代碼抽象化程度很高,嵌套層級非常...

    airborne007 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<