国产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
主站蜘蛛池模板: 边做边爱边吃奶叫床的视频 | 91亚洲国产成人久久精品网址 | 国内精品久久久久 | 三级第一页| 国产成人精品一区 | 亚洲第一导航 | 一级一级一级毛片免费毛片 | 在线观看国产欧美 | 欧美视频精品一区二区三区 | 亚洲综合欧美日本另类激情 | 日本三级成人中文字幕乱码 | 黄色一级视频免费观看 | 91视频一区 | 欧美国产日韩一区二区三区 | 国产手机视频在线观看 | 亚洲一区二区视频在线观看 | 欧美 亚洲 中文字幕 | 亚洲综合欧美 | 欧美日韩视频一区二区三区 | 欧美地区一二三 | 特黄一级毛片 | 久久亚洲国产成人影院 | 欧美激情亚洲一区中文字幕 | 日韩一区二区三区四区不卡 | 一区二区三区成人 | 国产精品视频第一页 | 亚洲一区二区三区成人 | 亚洲欧洲国产成人综合一本 | 欧美在线看欧美视频免费网站 | 国内久久| 亚洲精品一二区 | 欧美 亚洲 校园 第一页 | 香蕉久久网| 欧美成人精品高清在线播放 | 欧美激情亚洲一区中文字幕 | 欧美日韩性视频一区二区三区 | 波多野吉衣在线观看 | 日韩在线视频一区 | 亚洲免费a| 国产精品久久久久久久y | 久久国产精品成人免费 |