React.createElement(type, props, children);
function isValidElementType(type) {
return typeof type === 'string' ||
typeof type === 'function' ||
type === REACT_FRAGMENT_TYPE || // Symbol(react.fragment)
type === REACT_CONCURRENT_MODE_TYPE || // Symbol(react.concurrent_mode)
type === REACT_PROFILER_TYPE || // Symbol(react.profiler)
type === REACT_STRICT_MODE_TYPE || // Symbol(react.strict_mode)
type === REACT_SUSPENSE_TYPE || // Symbol(react.suspense)
type === REACT_SUSPENSE_LIST_TYPE || // Symbol(react.suspense_list)
typeof type === 'object' &&
type !== null &&
(type.$$typeof === REACT_LAZY_TYPE || // Symbol(react.lazy)
type.$$typeof === REACT_MEMO_TYPE || // Symbol(react.memo)
type.$$typeof === REACT_PROVIDER_TYPE || // Symbol(react.provider)
type.$$typeof === REACT_CONTEXT_TYPE || // Symbol(react.context)
type.$$typeof === REACT_FORWARD_REF_TYPE || // Symbol(react.forward_ref)
type.$$typeof === REACT_FUNDAMENTAL_TYPE || // Symbol(react.fundamental)
type.$$typeof === REACT_RESPONDER_TYPE); // Symbol(react.responder)
}
function createElementWithValidation(type, props, children) {
var validType = isValidElementType(type);
if (!validType) {
var info = '';
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, or you might have mixed up default and named imports.";
}
var sourceInfo = getSourceInfoErrorAddendumForProps(props);
if (sourceInfo) {
info += sourceInfo;
} else {
info += getDeclarationErrorAddendum();
}
var typeString = void 0;
if (type === null) {
typeString = 'null';
} else if (Array.isArray(type)) {
typeString = 'array';
} else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {
typeString = '<' + (getComponentName(type.type) || 'Unknown') + ' />';
info = ' Did you accidentally export a JSX literal instead of a component?';
} else {
typeString = typeof type;
}
warning$1(false, 'React.createElement: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', typeString, info);
}
var element = createElement.apply(this, arguments);
// return null的情况
if (element == null) {
return element;
}
// 如果agrument.length长度为3的话执行
if (validType) {
for (var i = 2; i < arguments.length; i++) {
validateChildKeys(arguments[i], type);
}
}
// 如果节点的类型是fragment, 这种节点比较特殊,它是这样的<></>
if (type === REACT_FRAGMENT_TYPE) {
validateFragmentProps(element);
} else {
// 验证你是一个 一个普通HTMLElement元素,还是一个class元素
validatePropTypes(element);
}
return element;
}
/**
* @description 创建一个ReactElement元素
* @param {*} type 它可以是一个string,或者是一个函数,如果是一个函数的话,会验证它的函数的原型是谁
* @param {*} config props与ref与key的设置
* @param {*} children 子元素,可以是数组,也可以是单个元素
*/
function createElement(type, config, children) {
var propName = void 0;
// 设置props
var props = {};
var key = null;
var ref = null;
var self = null;
var source = null;
// 这里是传递给子元素的props的设置,和ref与key的设置,还有__self,__source
if (config != null) {
if (hasValidRef(config)) {
ref = config.ref;
}
if (hasValidKey(config)) {
key = '' + config.key;
}
self = config.__self === undefined ? null : config.__self;
source = config.__source === undefined ? null : config.__source;
for (propName in config) {
// 过滤ref,key,__self,__source
/*
var RESERVED_PROPS = {
key: true,
ref: true,
__self: true,
__source: true
};
*/
const bool = !RESERVED_PROPS.hasOwnProperty(propName);
if (hasOwnProperty$1.call(config, propName) && bool) {
props[propName] = config[propName];
}
}
}
// 检测参数个,如果只有3个值,证明children是一个元素,如果多余3个值,children是一个数组,
// 并将它加入到props.chlidren里面
var childrenLength = arguments.length - 2;
if (childrenLength === 1) {
props.children = children;
} else if (childrenLength > 1) {
var childArray = Array(childrenLength);
for (var i = 0; i < childrenLength; i++) {
childArray[i] = arguments[i + 2];
}
{
// 如果支持Object.freeze,将子元素冻结
if (Object.freeze) {
Object.freeze(childArray);
}
}
props.children = childArray;
}
// 如果type存在,并且具备defaultProps属性时,此时type一般为函数类型,将defaultProps的value赋值到props里面,注意这里不是递归的哦,只处理第一层
if (type && type.defaultProps) {
var defaultProps = type.defaultProps;
for (propName in defaultProps) {
if (props[propName] === undefined) {
props[propName] = defaultProps[propName];
}
}
}
// 有没有key或ref
{
if (key || ref) { // 如果key存在或者ref存在
var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type;
if (key) {
defineKeyPropWarningGetter(props, displayName);
}
if (ref) {
defineRefPropWarningGetter(props, displayName);
}
}
}
return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
}
/**
* @description 返回一个ReactElement对象
* @param {*} type
* @param {*} props
* @param {*} key
* @param {string|object} ref
* @param {*} owner
* @param {*} self
* @param {*} source
* @internal
*/
var ReactElement = function (type, key, ref, self, source, owner, props) {
var element = {
// This tag allows us to uniquely identify this as a React Element
$$typeof: REACT_ELEMENT_TYPE,
// Built-in properties that belong on the element
type: type,
key: key,
ref: ref,
props: props,
// Record the component responsible for creating this element.
_owner: owner
};
{
// 设置一个react.element的仓库
element._store = {};
// 属性描述符号
// https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
// https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties
// 设置属性描述符
Object.defineProperty(element._store, 'validated', {
configurable: false,
enumerable: false,
writable: true,
value: false
});
// 设置属性描述符
Object.defineProperty(element, '_self', {
configurable: false,
enumerable: false,
writable: false,
value: self
});
// 设置属性描述符号
Object.defineProperty(element, '_source', {
configurable: false,
enumerable: false,
writable: false,
value: source
});
// 冻结一个对象,冻结的对象不允许被修改
if (Object.freeze) {
Object.freeze(element.props);
Object.freeze(element);
}
}
return element;
};