ReactElement
源碼筆記ReactElement
經過 createElement
建立,調用該方法須要 傳入三個參數:react
type
指代這個ReactElement
的類型函數
config
指代這個ReactElement
的屬性對象ui
children
指代這個ReactElement
的子元素節點this
'div'
,'p'
表明原生DOM,稱爲HostComponent
Component
或者 PureComponent
的組件,稱爲ClassComponent
function Component
Fragment
、AsyncMode
等是 Symbol,會被特殊處理//源碼位置: packages/react/src/ReactElement.js // createElement函數 export function createElement(type, config, children){ // 1、處理config // 1. 判斷config是否爲空 // 2. 提取保留屬性(key, ref, self, soure) // 3. 其他屬性添加到新的props對象中 for(propName in config){ if( hasOwnProperty.call(config, propName)&& !RESERVED_PROPS.hasOwnProperty(propName) ){ props[propName] = config[propName] } } // 2、處理children => props.children // (children能夠超過一個),處理事後的children 被放入 props.children const childrenLength = arguments.length - 2; if (childrenLength === 1) { props.children = children; } else if (childrenLength > 1) { const childArray = Array(childrenLength); for (let i = 0; i < childrenLength; i++) { childArray[i] = arguments[i + 2]; } props.children = childArray; } // 3、處理type的 defaultProps if(type && type.defaultProps) { const defaultProps = type.defaultProps; for (propName in defaultProps) { if(props[propName] === undefined) { props[propName] = defaultProps[propName] } } } // 4、返回一個ReactElement()函數 return ReactElement( type, key, ref, self, source, ReactCurrentOwner.current, props, ); }
注:
type.defaultProps
的由來:code
- 定義一個ClassComponent:
class Comp extends React.Component
- 能夠爲
Comp
設置一個defaultProps
:Comp.defaultProps = { value: 1 }
//源碼位置: packages/react/src/ReactElement.js // ReactElement 函數 const ReactElement = function(type, key, ref, self, source, owner, props){ const element = { // $$typeof用於標識 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, } // _DEV_ 代碼... return element; }