1mikasa1 / react-demo

0 stars 0 forks source link

React18源码-01createElement #4

Open 1mikasa1 opened 2 years ago

1mikasa1 commented 2 years ago

// 此函数主要完成了对props的赋值 function createElement(type, config, children) { var propName; // Reserved names are extracted var props = {}; var key = null; var ref = null; // self 和 source 是开发环境下对代码在编译器中位置等信息进行记录,用于开发环境下调试 var self = null; var source = null; // 1.将config中的属性添加到props中 if (config != null) { if (hasValidRef(config)) { ref = config.ref; { warnIfStringRefCannotBeAutoConverted(config); } } if (hasValidKey(config)) { { checkKeyStringCoercion(config.key); } key = '' + config.key; } self = config.self === undefined ? null : config.self; source = config.source === undefined ? null : config.source; for (propName in config) { if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { props[propName] = config[propName]; } } } // 2.childrenLength用于判断createElement接收到的参数是否多于三个,若是则从第三个开始就都是child,并将他们放入数组中,并将引用值传给props.children 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]; } { // 冻结childArray,让其不可以被修改 if (Object.freeze) { Object.freeze(childArray); } } props.children = childArray; } // Resolve default props // 3.判断是否有默认props属性,并对props上没有的属性进行添加 if (type && type.defaultProps) { var defaultProps = type.defaultProps; for (propName in defaultProps) { if (props[propName] === undefined) { props[propName] = defaultProps[propName]; } } } { if (key || ref) { //type为ReactElement的类型,有字符串(html原来的标签类型)、class类型、funtion类型、Fragment等等; var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type; // 为props中添加key和ref属性,用于警告那些调用props.key||props.ref的人,这两个属性不会通过props传递 if (key) { defineKeyPropWarningGetter(props, displayName); } if (ref) { defineRefPropWarningGetter(props, displayName); } } } return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props); }

1mikasa1 commented 2 years ago

var ReactElement = function (type, key, ref, self, source, owner, props) { // react元素 var element = { // 唯一标识,确定是否属于ReactElement; $$typeof: REACT_ELEMENT_TYPE, type: type, key: key, ref: ref, props: props, // todo Record the component responsible for creating this element. _owner: owner };

{ // todo element._store = {}; Object.defineProperty(element._store, 'validated', { configurable: false, enumerable: false, writable: true, value: false }); // self and source are DEV only properties. Object.defineProperty(element, '_self', { configurable: false, enumerable: false, writable: false, value: self }); // Two elements created in two different places should be considered // equal for testing purposes and therefore we hide it from enumeration. Object.defineProperty(element, '_source', { configurable: false, enumerable: false, writable: false, value: source }); if (Object.freeze) { Object.freeze(element.props); Object.freeze(element); } } return element; };