1.关于JSX底层处理机制
第一步:把我们编写的JSX语法,编译为virtualDOM对象
虚拟DOM对象:框架自己内部构建的一套对象体系,对象的相关成员都是React内部规定的,基于这些属性描述出,我们所构建视图中的DOM节点的相关特性特征!!
@1 基于babel-preset-react-app 把JSX编译为React.createElement(...)这种格式!!
只要是元素节点,必然会基于createElement进行处理
+ele: 元素标签名 或组件
+props:元素的属性集合(对象),如果没有设置过任何的属性,则为null
+children:第三个及以后的参数,都是当前元素的子节点
可以使用babeljs.io这个网站,在线将JSX语法编译为React.createElement()
//jsx语法
root.render(
<>
<h2 className="title">666</h2>
<div className="box">
<span>{x}</span>
<span>{y}</span>
</div>
</>
);
//对应的React.createElement()
React.createElement(
React.Fragment,
null,
React.createElement(
"h2",
{className: "title"},
"666"
),
React.createElement(
"div",
{className: "box"},
React.createElement("span", null, x),
React.createElement("span", null, y)
)
)
@2 再把createElement方法执行,创建出virtualDOM!(JSX元素,JSX对象,ReactChild对象)
virtualDOM = {
$$typeof: Symbol(react.element),
ref: null,
key: null,
type: 标签名或组件,
//存储了元素的相关属性以及子节点信息
props:{
元素的相关属性,
children:子节点信息,没有子节点则没有这个属性,属性值可能是一个值,也可能是一个数组
}
}
我们打印一下得到的React.createElement()
得到的就是virtualDOM
基于以上知识,我们手写一个函数实现React.createElement()功能
export function createElement(ele, props, ...children){
let virtualDOM = {
$$typeof: Symbol('react.element'),
key: null,
ref: null,
type: null,
props: {}
};
let len = children.length;
virtualDOM.type = ele;
if(props !== null){
virtualDOM.props = {
...props
};
}
if(len === 1) virtualDOM.props.children = children[0]
if(len > 1) virtualDOM.props.children = children
return virtualDOM;
}
{}语法当中可以直接渲染React.createElement()
{React.createElement('button', null, '提交')}
{}语法中,不能直接嵌入除数组外的其他对象,但是有一个对象是可以直接嵌入的:JSX元素对象-virtualDOM,以及样式对象