【React源码解读】react-element
在线源码地址:https://github.com/facebook/react/blob/master/packages/react/src/ReactElement.js
// 源码 ReactElement.js
export function createElement(type, config, children) {
// 处理参数
return ReactElement(
type,
key,
ref,
self,
source,
ReactCurrentOwner.current,
props,
);
}
/**
type: 节点类型
原生节点 string
自己申明组件 classComponent funcitonComponent
使用react原生组件(Symbol,会被特殊处理)
Fragment: REACT_FRAGMENT_TYPE,
StrictMode: REACT_STRICT_MODE_TYPE,
Suspense: REACT_SUSPENSE_TYPE,
*/
/**
config:写在jsx标签上的所有的attrs,以key-value形式存储
需要在config对象中筛选出我们认为是真正props内容以及特殊的key,ref属性
*/
/**
children:标签中间放置的一些内容
*/
/** 从源码可以看出虽然创建的时候都是通过config传入的,
但是key和ref不会跟其他config中的变量一起被处理,
而是单独作为变量出现在ReactElement上。
*/
// 源码 ReactElement.js
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
}
/**
$$typeof: 用来标识我们的Element是什么类型的
比如我们在写jsx代码的时候,所有的节点都是通过createElement创建的,那么它的$$typeof就永远是REACT_ELEMENT_TYPE,这点需要我们去记住。
因为,$$typeof在后续我们真正进行一个应用更新的时候,它如何渲染到dom的过程当中,它是经常要被用到的,它是用来一个判断的
大家可能会问了,我们写react应用的时候,大部分时间都是在写jsx,那么是不是所有的节点都是$$typeof?
也存在一些特殊情况,特殊情况和平台有关。在react-dom中,有个api叫React.createPortal,它返回的对象和上述类似,只不过它的$$typeof是REACT_PORTAL_TYPE
*/
/**
type: 记录节点类型,是原生组件还是class function Component or other
*/
小结:
ReactElement只是一个用来承载信息的容器,他会告诉后续的操作这个节点的以下信息:
type类型,用于判断如何创建节点
key和ref这些特殊信息
props新的属性内容
$$typeof用于确定是否属于ReactElement
这些信息对于后期构建应用的树结构是非常重要的,而React通过提供这种类型的数据,来脱离平台的限制