instantiateReactComponent源码

instantiateReactComponent用于将ReactNode转化为用于挂载、更新到页面视图上的实例。

 

'use strict';

var _prodInvariant = require('./reactProdInvariant'),// 生产环境React形式带url报错
    _assign = require('object-assign');

// 用于更新或挂载用户自定义组件的协调器
var ReactCompositeComponent = require('./ReactCompositeComponent');

// 用于创建空组件
var ReactEmptyComponent = require('./ReactEmptyComponent');

// 用于创建React封装DOM标签组件、或文本组件
var ReactHostComponent = require('./ReactHostComponent');

var getNextDebugID = require('./getNextDebugID');

// invariant(condition,format,a,b,c,d,e,f) condition为否值,替换format中的"%s",并throw error报错
var invariant = require('fbjs/lib/invariant');

// warning(condition,format) condition为否值,替换format中的"%s",并console.error警告
var warning = require('fbjs/lib/warning');

// 继承ReactCompositeComponent,并将instantiateReactComponent赋值给原型方法,避免循环依赖
// 用于挂载用户自定义组件创建的元素
var ReactCompositeComponentWrapper = function (element) {
  this.construct(element);
};
_assign(ReactCompositeComponentWrapper.prototype, ReactCompositeComponent, {
  _instantiateReactComponent: instantiateReactComponent
});

// 适用于提示require加载的文件没有export
function getDeclarationErrorAddendum(owner) {
  if (owner) {
    var name = owner.getName();
    if (name) {
      return ' Check the render method of `' + name + '`.';
    }
  }
  return '';
}

// 内部组件书写形式,包含mountComponent、receiveComponent,用于挂载组件
// 用户自定义的组件包含render方法,指示待绘制的ReactNode包含哪些元素,挂载mountComponent却通过内部组件实现
function isInternalComponentType(type) {
  return typeof type === 'function' && typeof type.prototype !== 'undefined' && 
    typeof type.prototype.mountComponent === 'function' && 
    typeof type.prototype.receiveComponent === 'function';
}

// 参数node为ReactNode,包含ReactElement、ReactFragment、ReactText
//    其中,ReactElement又可分为ReactComponentElement、ReactDomElement两类
// 就ReactComponentElement为例,ReactComponentElement只设置了构造函数ReactComponent、props
//    其中,ReactComponent设定render方法用于创建ReactComponentElement元素下含的ReactNode
//    挂载到视图中,通过间接调用ReactCompositeComponent构造函数中的mountComponent方法实现
function instantiateReactComponent(node, shouldHaveDebugID) {
  var instance;

  // 空组件,由ReactEmptyComponent默认调用ReactDOMEmptyComponent创建
  if (node === null || node === false) {
    instance = ReactEmptyComponent.create(instantiateReactComponent);

  // React封装DOM标签组件、用户自定义组件处理
  } else if (typeof node === 'object') {
    var element = node;
    var type = element.type;

    // type类型错误报错,提示require加载的文件没有export
    if (typeof type !== 'function' && typeof type !== 'string') {
      var info = '';
      if (process.env.NODE_ENV !== 'production') {
        if (type === undefined || typeof type === 'object' && 
          type !== null && Object.keys(type).length === 0) {
          info += ' You likely forgot to export your component from the file ' 
            + 'it\'s defined in.';
        }
      }
      info += getDeclarationErrorAddendum(element._owner);
      !false ? process.env.NODE_ENV !== 'production' ? 
        invariant(false, 'Element type is invalid: expected a string (for built-in components) ' 
          + 'or a class/function (for composite components) but got: %s.%s', 
          type == null ? type : typeof type, info) 
        : _prodInvariant('130', type == null ? type : typeof type, info) : void 0;
    }

    // React封装DOM标签组件
    if (typeof element.type === 'string') {
      instance = ReactHostComponent.createInternalComponent(element);
    
    // React封装的内部组件(实现了mountComponent等方法)不能使用字符串引用的暂时替代方案
    } else if (isInternalComponentType(element.type)) {
      instance = new element.type(element);

      // 维持旧有api的有效性
      if (!instance.getHostNode) {
        instance.getHostNode = instance.getNativeNode;
      }

    // 用户自定义组件,创建原型继承ReactCompositeComponent类的ReactCompositeComponentWrapper实例
    } else {
      instance = new ReactCompositeComponentWrapper(element);
    }

  // 文本组件
  } else if (typeof node === 'string' || typeof node === 'number') {
    instance = ReactHostComponent.createInstanceForText(node);
  } else {
    !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Encountered invalid React node of type %s', typeof node) : _prodInvariant('131', typeof node) : void 0;
  }

  if (process.env.NODE_ENV !== 'production') {
    process.env.NODE_ENV !== 'production' ? warning(typeof instance.mountComponent === 'function' && typeof instance.receiveComponent === 'function' && typeof instance.getHostNode === 'function' && typeof instance.unmountComponent === 'function', 'Only React Components can be mounted.') : void 0;
  }

  // 初始化参数
  instance._mountIndex = 0;
  instance._mountImage = null;

  if (process.env.NODE_ENV !== 'production') {
    instance._debugID = shouldHaveDebugID ? getNextDebugID() : 0;
  }

  // Object.preventExtensions使对象属性不可扩展,但可修改
  if (process.env.NODE_ENV !== 'production') {
    if (Object.preventExtensions) {
      Object.preventExtensions(instance);
    }
  }

  return instance;
}

module.exports = instantiateReactComponent;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值