Element 为null或者是false

2,357 阅读2分钟

先来看看(1)element 为null或者是false

    node == null || node == false

React 组件必须包含一个 render函数,这个render函数必须返回一个东西。如果你啥也不显示,那就返回一个null或者是false。

这种情况就是一个空组件,啥也不显示。

     if (node === null || node === false) {
        instance = new ReactEmptyComponent(instantiateReactComponent);----------(1)
      }

这个时候是调用 ReactEmptyComponent 方法。

ReactEmptyComponent 方法。

ReactEmptyComponent 模块中的核心是ReactEmptyComponent构造函数,以及一些原型方法。 ReactEmptyComponent 构造函数,将当前方法 instantiateReactComponent,当做参数来构造实例。

先来看看构造函数

    var ReactEmptyComponent = function (instantiate) {
        this._currentElement = null;
        this._rootNodeID = null;
        this._renderedComponent = instantiate(placeholderElement);
    };

这里 placeholderElement:ReactElement.createElement('noscript'); 也就是 placeholderElement 是一个 element。如下所示:

React会将return 一个 null或者是一个false的空组件也会包装一些,变为 type 为 'noscript'的 element。而后再将他给 instantiateReactComponent 方法生成 要挂载的组件,最终将其赋值给 _renderedComponent。

     this._renderedComponent = instantiate(placeholderElement);

而 instantiate(placeholderElement) 的最终样子如下: 这其实就是在 node 为 Object,且 element.type 为string的情况,也就是 情况(2)要做的事情。这个要去 element 为 Object的 文章中去看看。我们这里先略过。

ReactEmptyComponent 的原型属性

    assign(ReactEmptyComponent.prototype, {
      construct: function (element) {},
      mountComponent: function (rootID, transaction, context) {
        transaction.getReactMountReady().enqueue(registerNullComponentID, this);
        this._rootNodeID = rootID;
        return ReactReconciler.mountComponent(this._renderedComponent, rootID, transaction, context);
      },
      receiveComponent: function () {},
      unmountComponent: function (rootID, transaction, context) {
        ReactReconciler.unmountComponent(this._renderedComponent);
        ReactEmptyComponentRegistry.deregisterNullComponentID(this._rootNodeID);
        this._rootNodeID = null;
        this._renderedComponent = null;
      }
    });

construct

construct方法是空的,就不再赘述。

mountComponent

顾名思义,这个方法就是 挂载组件的方法。 这里的参数情况如下: rootID 是当前组件要挂载的 位置 transaction 是 ReactReconcileTransaction

    mountComponent: function (rootID, transaction, context) {
        '
            transaction.getReactMountReady() 会拿到一个 CallbackQueue的实例。
            这里调用 CallbackQueue的实例方法 enqueue,入队一个 registerNullComponentID 方法。
        '
        transaction.getReactMountReady().enqueue(registerNullComponentID, this);
        '
            为 _rootNodeID 赋值
        '
        this._rootNodeID = rootID;
        '
            返回一个东西。
        '
        return ReactReconciler.mountComponent(this._renderedComponent, rootID, transaction, context);
      },
registerNullComponentID 方法
    function registerNullComponentID() {
          ReactEmptyComponentRegistry.registerNullComponentID(this._rootNodeID);
    }
ReactEmptyComponentRegistry.registerNullComponentID

方法的作用是将组件标记为已经渲染为 null

    function registerNullComponentID(id) {
        nullComponentIDsRegistry[id] = true;
    }

页面上的真实展示情况如下:

null 组件被渲染为 红框中的内容。

ReactReconciler.mountComponent

看看mountComponent方法返回的东西是什么。

之前我们看过这个方法任意门。这里我们再来看看吧。

参数internalInstance辨识实例的属性 this._renderedComponent的值。 也就是 instantiateReactComponent (placeholderElement);的值。 placeholderElement是一个字符串 'noscript' 所以,instantiateReactComponent (placeholderElement) 就是在 element 为Object,且 其type为string的时候初始化一个挂载实例。另外的文章会有讲述任意门

总之一句话。这里instantiateReactComponent (placeholderElement)==>this._renderedComponent ==>internalInstance.

值就是 一个 将要挂载的 实例,这个实例与上边第一个图中展示的实例是类似的。

    mountComponent: function (internalInstance, rootID, transaction, context) {
        
        '
            这里会生成 一个makeup,形如:
            <noscript data-reactid=".0.1"></noscript>
        '
        var markup = internalInstance.mountComponent(rootID, transaction, context);
        
        if (internalInstance._currentElement && internalInstance._currentElement.ref != null) {
          transaction.getReactMountReady().enqueue(attachRefs, internalInstance);
        }
        return markup;
    },