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

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

不言
不言nach vorne
2018-10-20 14:42:262616Durchsuche

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 相关)
                                                          _|_

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
    );
}

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;
}

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;
},

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;
}

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;
}
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 相关下一篇讲解)
                                                          _|_

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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen

In Verbindung stehende Artikel

Mehr sehen