Le contenu de cet article concerne la première analyse de rendu 2 de React (éléments DOM purs). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Dans l'article précédent , nous avons présenté comment l'objet de niveau supérieur ReactCompositeComponent[T] est construit. Voyons ensuite ce que fait batchedMountComponentIntoNode.
La pile d'appels qui sera expliquée dans cet article ressemble à ceci :
|=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 相关) _|_
Si vous regardez le code source, nous remarquerons beaucoup de code lié aux transactions. ignorez-le pour l’instant et nous en discuterons plus tard. Cela sera expliqué dans les articles suivants. Pour l'instant, on comprend que lors de l'appel de transaction.perform, il s'agit en fait d'un appel de fonction sur le premier paramètre. Après avoir ignoré du code de modèle, ce qui fait réellement le travail, c'est la méthode 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 est utilisé pour créer des éléments DOM, tandis que ReactMount._mountImageIntoNode est le DOM nouvellement créé L'élément est attaché à la page. ReactReconciler.mountComponent appellera la méthode mountComponent de ReactCompositeComponent[T]. Avant d'examiner la méthode mountComponent, vous devez d'abord préparer hostContainerInfo, qui est généré par 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; }
Maintenant, la relation entre les instances est la suivante :
Continuons à regarder la méthode 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; },
Lors de l'exécution sur var child = this._instantiateReactComponent
, le fichier instantiateReactComponent
mentionné dans l'article précédent sera appelé :
// 文件位置: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 exécutera ReactDefaultInjection.inject()
pour injecter ReactDOMComponent dans ReactHostComponent pendant l'exécution. ReactHostComponent.createInternalComponent finira par appeler 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; }
Nous nommons l'instance renvoyée ReactDOMComponent[ins].
ReactReconciler.mountComponent appellera la méthode mountComponent de ReactDomComponent, qui impliquera du contenu HTML lié au DOM, que nous expliquerons dans le prochain article.
Jetons maintenant un œil à la relation entre chaque instance :
La pile d'appels jusqu'à présent :
|=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 相关下一篇讲解) _|_
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!