在编辑阶段 jsx标签被babel转化为React.createElement的调用,然后React.createElement函数执行后返回虚拟DOM,最后调用render方法生成真实dom
jsx语法
<div id="compId">
<p>text1</p>
<p>text2</p>
</div>
React.createElement函数参数说明 React.createElement(标签名,属性props对象, 子节点1,子节点2 …)
- 第一个参数必填,另两个参数选填
- 参数:标签名,属性对象,子节点
- 返回值:虚拟DOM对象
jsx标签被babel转化为React.createElement调用形式为
React.createElement('div',{id:'compId'}, [
React.createElement('p',null, 'text1'),
React.createElement('p',null, 'text2')
])
React.createElement返回的虚拟dom数据结构如下
{
"type":"div",
"key":null,
"ref":null,
"props":{
"id":"comp",
"children":[
{"type":"p","key":null,"ref":null,"props":{"children":"text1"}},
{"type":"p","key":null,"ref":null,"props":{"children":"text2"}}
]
}
}
render方法接受两个参数 render(Comp, document.getElementById('root'))
-
第一个参数虚拟dom
-
第二个参数真实dom
const render = (virtualDom,container) => {
const {type, props} = virtualDom
const dom = document.createElement(type)
Object.keys(props).filter(prop => prop !=='children').forEach(prop => {
//将props 属性挂在dom结构上,但排除children属性
// 注意 这是简单对属性处理,还需要对style 事件进行特色处理
dom[prop] = props[prop]
})
// 如果children是数组,递归调用 render函数
// 注意这是react.16之前版本 stack 递归渲染方式,但会存在问题,如果子阶段很多,js执行时间过长,会操作页面卡顿
if(Array.isArray(props.children)) {
props.children.forEach(child => render(child, dom))
}else {
dom.textContent = props.children
}
container.appendChild(dom)
}
render(Comp, document.getElementById('root'))
在jsx标签被babel转化为React.createElement的调用,生成虚拟DOM,render函数接受虚拟DOM 生成真实dom找个过程,需要关注是 数据结构的变化,render函数是对虚拟dom的树形结构进行深层遍历,生成对应dom节点
如果有数据结构的基础,特别是树形数据结构,对jsx标签到真实dom过程有比较深的理
大家对jsx标签到真实dom整个过程有什么看法,欢迎大家在评论区进行评论