ホームページ >ウェブフロントエンド >jsチュートリアル >React の最初のレンダリング分析 2 (純粋な DOM 要素)
この記事は React の最初のレンダリング解析 2 (純粋な 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.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; }
各インスタンス間の関係は次のようになります:
引き続き 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## が実行されます。 #File:
// 文件位置: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 に挿入します。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 関連のコンテンツが含まれます。これについては次の記事で説明します。
ここで、各インスタンス間の関係を見てみましょう:
##これまでのコールスタック:
|=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 相关下一篇讲解) _|_
以上がReact の最初のレンダリング分析 2 (純粋な DOM 要素)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。