jsx代码如何变成dom
- 一、三个问题考察对jsx的理解
- 二、jsx的本质以及它和js之间是什么关系?
- 2.1 jsx是什么
- 2.2 和js的关系
- 2.3 jsx的本质
- 三、为什么要用jsx?不用会有什么后果
- 四、jsx背后的功能模块是什么?这个功能模块都做了哪些事情?
- 4.1 createElement
- 1.入参分析
- 2.函数体拆解
- 4.2 ReactElement
- 4.3 虚拟dom和reactDom.render
- 4.4 总结
一、三个问题考察对jsx的理解
- jsx的本质是什么,它和js之间是什么关系?
- 为什么要用jsx?不用会有什么后果
- jsx背后的功能模块是什么?这个功能模块都做了哪些事情?
二、jsx的本质以及它和js之间是什么关系?
2.1 jsx是什么
jsx是JavaScript的一种语法拓展,它和模板语言很接近,但是它充分具备JavaScript的能力。
2.2 和js的关系
因为jsx是JavaScript的拓展,所以直接决定了浏览器不会像天然支持JavaScript一样支持jsx。
但是既然jsx充分具备JavaScript的能力,那么jsx是如何在js中生效的呢?
其实在react官网中就给出了答案,jsx会被编译为React.createElement(),它将返回一个“React Element”的js对象。
编译这个动作是由Babel来完成的。Babel是一个工具链,主要用于将es2015+版本的代码转换为向后兼容的js语法,以便能够运行在当前和旧版本的浏览器或其他环境。
在babel官网中,可以看到编译前后的代码
2.3 jsx的本质
当我们在写jsx时,实际上编译后就是React.createElement。
jsx的本质就是调用js中的React.createElement语法糖。
三、为什么要用jsx?不用会有什么后果
既然jsx等价于一次React.createElement调用,那么React官方为什么不直接引导我们用ReactElement来创建元素?
因为当jsx内容更多时,编译之后的代码会变得很复杂,嵌套不清晰。
所以jsx语法糖允许我们使用最为熟悉的类HTML标签语法来创建虚拟DOM,降低学习成本的同时,也提升了研发效率和体验。
四、jsx背后的功能模块是什么?这个功能模块都做了哪些事情?
4.1 createElement
1.入参分析
export function createElement(type,config,children)
type:标识节点类型
config:以对象形式传入,组件所有的属性都会以键值对的形式存储在config中
children:以对象形式传入,它记录的是组件标签之间嵌套的内容
2.函数体拆解
createElement的步骤其实是在格式化数据。将开发传入的数据根据ReactElement的预期做一层格式化,最终调用ReactElement实现元素的创建。
4.2 ReactElement
主要做的事情就是组装。ReactElement把传入的参数按照一定的规范,组装进Element对象里,然后返回给React.createElement,最后React.createElement交回给开发者手中。
可以通过打印验证这一点。输出的确实是标准的ReactElement实例。本质是以js对象形式存在的对dom的描述,也就是虚拟dom。
4.3 虚拟dom和reactDom.render
既然是虚拟dom,那和渲染到页面上的真实dom一定是有差距的,它们之间的差距就是由reactDom.render方法来填补的。
reactDOM.render经常出现在项目的入口文件中。
reactDOM.render的入参分析
4.4 总结
jsx背后的功能模块的内容以及做了的事情:
1.通过babel将jsx代码编译为React.createElement的调用。
2.React.createElement将传入的参数包括type,config,children格式化为ReactElement预期的格式。
3.调用ReactElement后组装成ReactElement对象,返回给React.createElement,最终生成虚拟dom。
4.虚拟dom作为ReactDOM.render的入参,经过渲染处理生成真实DOM。