Heim > Web-Frontend > js-Tutorial > React erste Rendering-Analyse 2 (reine DOM-Elemente)

React erste Rendering-Analyse 2 (reine DOM-Elemente)

不言
Freigeben: 2018-10-20 14:42:26
nach vorne
2654 Leute haben es durchsucht

Der Inhalt dieses Artikels handelt von der ersten Rendering-Analyse 2 (reine DOM-Elemente). Ich hoffe, dass er für Sie hilfreich ist.

Im vorherigen Artikel haben wir vorgestellt, wie das Top-Level-Objekt ReactCompositeComponent[T] aufgebaut ist. Schauen wir uns als Nächstes an, was „batchedMountComponentIntoNode“ tut.

Der in diesem Artikel erläuterte Aufrufstapel sieht folgendermaßen aus:

|=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 相关)
                                                          _|_
Nach dem Login kopieren

Wenn Sie sich den Quellcode ansehen, werden wir viel transaktionsbezogenen Code bemerken. Wir werden ihn ignorieren Dies wird vorerst im Artikel erläutert. Derzeit kann verstanden werden, dass es sich beim Aufruf von „transaktion.perform“ tatsächlich um einen Funktionsaufruf für den ersten Parameter handelt. Nachdem Sie einen Teil des Vorlagencodes übersprungen haben, übernimmt die mountComponentIntoNode-Methode tatsächlich die Arbeit.

// 文件位置: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
    );
}
Nach dem Login kopieren

ReactReconciler.mountComponent wird zum Erstellen von DOM-Elementen verwendet ReactMount._mountImageIntoNode ist das neu erstellte DOM Das Element wird an die Seite angehängt. ReactReconciler.mountComponent ruft die mountComponent-Methode von ReactCompositeComponent[T] auf. Bevor Sie sich die mountComponent-Methode ansehen, müssen Sie zunächst hostContainerInfo vorbereiten, das von ReactDOMContainerInfo generiert wird:

// 文件位置: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;
}
Nach dem Login kopieren

Jetzt ist die Beziehung zwischen den Instanzen wie folgt:

React erste Rendering-Analyse 2 (reine DOM-Elemente)

Sehen Sie sich weiterhin die mountComponent-Methode an:

// 文件位置: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;
},
Nach dem Login kopieren

Beim Ausführen von var child = this._instantiateReactComponent wird die im vorherigen Artikel erwähnte instantiateReactComponent-Datei aufgerufen:

// 文件位置: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;
}
Nach dem Login kopieren

ReactDom wird beim Ausführen ausgeführt, um ReactDOMComponent in ReactHostComponent einzufügen.createInternalComponent ruft schließlich ReactDOMComponent auf: ReactDefaultInjection.inject()

// 文件位置: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;
}
Nach dem Login kopieren
Wir nennen die zurückgegebene Instanz ReactDOMComponent[ins].

ReactReconciler.mountComponent ruft die mountComponent-Methode von ReactDomComponent auf, die HTML-DOM-bezogene Inhalte umfasst, die wir im nächsten Artikel erläutern werden.

Jetzt werfen wir einen Blick auf die Beziehung zwischen den einzelnen Instanzen:

React erste Rendering-Analyse 2 (reine DOM-Elemente)

Der bisherige Aufrufstapel:

|=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 相关下一篇讲解)
                                                          _|_
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonReact erste Rendering-Analyse 2 (reine DOM-Elemente). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:segmentfault.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage