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;