ReactElement 源碼筆記
ReactElement 通過 createElement 創(chuàng)建,,調(diào)用該方法需要 傳入三個(gè)參數(shù):
type 指代這個(gè)ReactElement 的類型
config 指代這個(gè)ReactElement 的屬性對(duì)象
children 指代這個(gè)ReactElement 的子元素節(jié)點(diǎn)
- 字符串比如
'div' ,'p' 代表原生DOM,,稱為HostComponent
- Class 類型是我們繼承自
Component 或者 PureComponent 的組件,,稱為ClassComponent
- 方法就是
function Component
- 原生提供的
Fragment 、AsyncMode 等是 Symbol,,會(huì)被特殊處理
- TODO: 是否有其他的
//源碼位置: packages/react/src/ReactElement.js
// createElement函數(shù)
export function createElement(type, config, children){
// 一,、處理config
// 1. 判斷config是否為空
// 2. 提取保留屬性(key, ref, self, soure)
// 3. 其余屬性添加到新的props對(duì)象中
for(propName in config){
if(
hasOwnProperty.call(config, propName)&&
!RESERVED_PROPS.hasOwnProperty(propName)
){
props[propName] = config[propName]
}
}
// 二、處理children => props.children
// (children可以超過一個(gè)),,處理過后的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;
}
// 三,、處理type的 defaultProps
if(type && type.defaultProps) {
const defaultProps = type.defaultProps;
for (propName in defaultProps) {
if(props[propName] === undefined) {
props[propName] = defaultProps[propName]
}
}
}
// 四、返回一個(gè)ReactElement()函數(shù)
return ReactElement(
type,
key,
ref,
self,
source,
ReactCurrentOwner.current,
props,
);
}
注:type.defaultProps 的由來:
- 定義一個(gè)ClassComponent:
class Comp extends React.Component
- 可以為
Comp 設(shè)置一個(gè)defaultProps : Comp.defaultProps = { value: 1 }
//源碼位置: packages/react/src/ReactElement.js
// ReactElement 函數(shù)
const ReactElement = function(type, key, ref, self, source, owner, props){
const element = {
// $$typeof用于標(biāo)識(shí) 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;
}
|