国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

React首次渲染解析二(純DOM元素)

來源:懂視網 責編:小采 時間:2020-11-27 19:29:41
文檔

React首次渲染解析二(純DOM元素)

React首次渲染解析二(純DOM元素):本篇文章給大家帶來的內容是關于React首次渲染解析二(純DOM元素),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。上一篇文章中,介紹了頂層對象ReactCompositeComponent[T]是如何構造的,接下來我們看看 batchedMountCom
推薦度:
導讀React首次渲染解析二(純DOM元素):本篇文章給大家帶來的內容是關于React首次渲染解析二(純DOM元素),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。上一篇文章中,介紹了頂層對象ReactCompositeComponent[T]是如何構造的,接下來我們看看 batchedMountCom
本篇文章給大家帶來的內容是關于React首次渲染解析二(純DOM元素),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

上一篇文章中,介紹了頂層對象ReactCompositeComponent[T]是如何構造的,接下來我們看看 batchedMountComponentIntoNode 做了什么事情。

本文將要講解的調用棧是下面這個樣子的:

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

如果看源碼,我們會留意到很多transaction相關的代碼,我們暫時先將其忽略,會在后續的文章中進行講解。暫時可以理解為調用transaction.perform時,實際上就是對第一個參數進行函數調用。跳過一些模版代碼后,實際上做事情的是 mountComponentIntoNode 這個方法。

// 文件位置:src/renderers/dom/client/ReactMount.js

function mountComponentIntoNode(
 wrapperInstance, // ReactCompositeComponent[T]
 container, // document.getElementById("root")
 transaction,
 shouldReuseMarkup,
 context
) {
 ...
 
 var markup = ReactReconciler.mountComponent(
 wrapperInstance,
 transaction,
 null,
 ReactDOMContainerInfo(wrapperInstance, container),
 context,
 0 /* parentDebugID */
 );

 ...
 
 ReactMount._mountImageIntoNode(
 markup,
 container,
 wrapperInstance,
 shouldReuseMarkup,
 transaction
 );
}

ReactReconciler.mountComponent 用于創建 DOM 元素,而 ReactMount._mountImageIntoNode 則是將剛創建的 DOM 元素掛載到頁面。ReactReconciler.mountComponent 會調用 ReactCompositeComponent[T]的 mountComponent 方法。在看 mountComponent 方法前,還需要先準備好 hostContainerInfo,由 ReactDOMContainerInfo 生成:

// 文件位置:src/renderers/shared/stack/reconciler/ReactContainerInfo.js

function ReactDOMContainerInfo(
 topLevelWrapper, // ReactCompositeComponent[T]
 node // document.getElementById("root")
) {
 var info = {
 _topLevelWrapper: topLevelWrapper,
 _idCounter: 1,
 _ownerDocument: node ?
 node.nodeType === DOC_NODE_TYPE ? node : node.ownerDocument : null,
 _node: node,
 _tag: node ? node.nodeName.toLowerCase() : null,
 _namespaceURI: node ? node.namespaceURI : null,
 };
 
 ...
 
 return info;
}

現在各實例間的關系是這樣的:

3778215164-5bc9e101a4f2e_articlex.png

再繼續看 mountComponent 方法:

// 文件位置:src/renderers/shared/stack/reconciler/ReactCompositeComponent.js

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

 // this._currentElement 為ReactElement[2](TopLevelWrapper)
 var publicProps = this._currentElement.props;
 var publicContext = this._processContext(context);

 // TopLevelWrapper
 var Component = this._currentElement.type;

 ...

 // Initialize the public class
 var doConstruct = shouldConstruct(Component);
 
 // 生成TopLevelWrapper 實例
 var inst = this._constructComponent(
 doConstruct,
 publicProps,
 publicContext,
 updateQueue
 );
 
 ...

 var markup;
 
 ...
 
 markup = this.performInitialMount(renderedElement,
 hostParent, hostContainerInfo, transaction, context

 ...

 return markup;
},

performInitialMount: function (renderedElement, hostParent,
 hostContainerInfo, transaction, context) {
 
 // TopLevelWrapper 實例
 var inst = this._instance;

 ...
 
 // If not a stateless component, we now render
 if (renderedElement === undefined) {
 // 返回值為 ReactElement[1]
 renderedElement = this._renderValidatedComponent();
 }

 // 返回 ReactNodeTypes.HOST
 var nodeType = ReactNodeTypes.getType(renderedElement);
 
 this._renderedNodeType = nodeType;
 
 // instantiateReactComponent.js
 var child = this._instantiateReactComponent(
 renderedElement,
 nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */
 );
 this._renderedComponent = child;

 var markup = ReactReconciler.mountComponent(
 child,
 transaction,
 hostParent,
 hostContainerInfo,
 this._processChildContext(context),
 debugID
 );

 ...

 return markup;
},

當運行到var child = this._instantiateReactComponent時,就會調用上篇文章說到的instantiateReactComponent文件:

// 文件位置:src/renderers/shared/stack/reconciler/instantiateReactComponent.js

function instantiateReactComponent(node, shouldHaveDebugID) {
 var instance;

 ...
 
 } else if (typeof node === 'object') {
 ...

 // element.type 為 ‘h1’
 if (typeof element.type === 'string') {
 instance = ReactHostComponent.createInternalComponent(element);
 } 

 return instance;
}

ReactDom 會在執行的時候,執行ReactDefaultInjection.inject()將 ReactDOMComponent 注入到 ReactHostComponent 中,ReactHostComponent.createInternalComponent 最終會調用 ReactDOMComponent:

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

function ReactDOMComponent(element) {
 // h1
 var tag = element.type;
 
 validateDangerousTag(tag);
 
 // ReactElement[1]
 this._currentElement = element;
 
 this._tag = tag.toLowerCase();
 this._namespaceURI = null;
 this._renderedChildren = null;
 this._previousStyle = null;
 this._previousStyleCopy = null;
 this._hostNode = null;
 this._hostParent = null;
 this._rootNodeID = 0;
 this._domID = 0;
 this._hostContainerInfo = null;
 this._wrapperState = null;
 this._topLevelWrapper = null;
 this._flags = 0;
}

我們將返回的實例命名為 ReactDOMComponent[ins]。

ReactReconciler.mountComponent 會調用 ReactDomComponent 的 mountComponent 方法,這就會涉及到 HTML DOM 相關的內容,我們在下一篇進行講解。

現在我們來看一下各實例間的關系:

773279841-5bcaa4696ab21_articlex.png

目前為止的調用棧:

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

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

React首次渲染解析二(純DOM元素)

React首次渲染解析二(純DOM元素):本篇文章給大家帶來的內容是關于React首次渲染解析二(純DOM元素),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。上一篇文章中,介紹了頂層對象ReactCompositeComponent[T]是如何構造的,接下來我們看看 batchedMountCom
推薦度:
標簽: 元素 首次 解析
  • 熱門焦點

最新推薦

猜你喜歡

熱門推薦

專題
Top
主站蜘蛛池模板: 一边摸一边叫床一边爽视频 | 国产精品久久久久久久久99热 | 九九久久99综合一区二区 | 一本色道久久88综合亚洲精品高清 | 亚洲伊人久久综合一区二区 | 精品二区| 国产成人精品视频一区二区不卡 | 国产精品区一区二区三 | 精品国产一区二区三区免费看 | 久久久久久久99久久久毒国产 | 五月天色综合 | 亚洲欧美另类日韩 | 日韩欧美制服 | 国产有码 | 欧美在线不卡视频 | 可以免费观看的毛片 | 国产精品视频第一区二区三区 | 欧美一区二区三区视频在线 | 香港一级a毛片在线播放 | 麻豆91视频 | 欧美专区在线观看 | 国产在线观看精品一区二区三区91 | 亚洲午夜一区 | 国产91精品一区二区视色 | 国产欧美日韩在线不卡第一页 | 国产成人久久精品亚洲小说 | 国产一区二区日韩欧美在线 | 欧美区国产区 | 国产手机在线αⅴ片无码观看 | 国产嘿咻视频 | 五月天婷婷视频 | 日本一区二区三区免费观看 | 欧美日韩国产一区二区 | 国产视频1| 图片一区| 日韩第二页 | 国产精品一区在线观看 | 久久精品成人国产午夜 | 日韩欧美在线免费观看 | 国产一区 在线播放 | 久久久精品麻豆 |