react读源码系列之ReactElement
Opened this issue · 0 comments
前言
我们上节中说到了JSX到javaScript的一个编译过程,在当中我们知道了最后我们的组件和标签都会转换为React.createElement方法的“产物”,这一节我们就来说说这个产物到底是什么?
源码解读
我们在git上面下载react源码,react源码地址
我们打开ReactElement.js,找到React.createElement的方法实现
export function createElement(type, config, children) {
// 处理参数
return ReactElement(
type,
key,
ref,
self,
source,
ReactCurrentOwner.current,
props,
);
}
const ReactElement = function(type, key, ref, self, source, owner, props) {
const 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,
};
return element
}
我们看见这个方法返回一个ReactElement对象,这个ReactElement对象就是上一节中所说的“产物”, 这一节我们就来聊聊这个ReactElement
我们先从方法的参数看起吧,createElement有3个参数 type, config, children
type: 指代这个ReactElement的类型
- 字符串比如div,p代表原生DOM,称为HostComponent
- Class类型是我们继承自Component或者PureComponent的组件,称为ClassComponent
- 方法就是functional Component
- 原生提供的Fragment、AsyncMode等是Symbol,会被特殊处理
- TODO: 是否有其他的
config:我们在源码中可以看到,ref, key这俩个属性是直接绑定在组件上的,而不是放在props中的
children:源码中会对参数的个数进行获取,如果是3个参数,则props.children = 第三个参数,如果超过3个参数,则后面的参数都会合并成一个数组,props.children = 合并后的数组。所以我们在使用this.props.children这个属性的时候要注意他的数据结构
在来看看ReactElement这个函数吧!!
从上面可以看到这个函数的参数都是很眼熟,type,key, ref, props这些常见的这里就不陈述了,我们说一下$$typeof这个属性,这是个啥呢,在这里可以看出来他是一个常量:REACT_ELEMENT_TYPE,但有一个特例:ReactDOM.createPortal的时候是REACT_PORTAL_TYPE,不过他不是通过createElement创建的,所以他应该也不属于ReactElement
_owner这个属性表示这个ReactElement是哪个组件创建的,我理解这个可能在和解、组件更新的过程中会用到,这个后面遇到了再来说