JSX如何变成DOM
入门React的时候,我们了解了神奇的JSX语法,当时的官方是建议使用JSX,作为小白的我当然是乖乖听话。想必现在大家都早已经习惯使用JSX,我们今天来了解一下它是如何成为DOM的。
JSX的本质
官方描述JSX是JavaScript的扩展语法,它充分具备JavaScript的能力,那么它是怎么做到的呢。这时候我能想到的就是官方霸霸给出的一句话,JSX会被编译成React.createElement(),它会返回一个叫做’React Element’的JS对象。首先编译这个动作,它是由Babel来完成的,我们知道Babel的主要功能是将ECMAScript2015+版本的代码转换成向后兼容的JavaScript语法,从而能运行在当前的浏览器中。其实,JSX也是由Babel来转换为Javascript代码的。
我随便找了一段项目里的简单组件的JSX代码放在Babel官网上,它会将其转换成React.createElement的调用。可以看到,所有的JSX标签都被转换成了React.createElement调用,大家明显能感受到,JSX相对而言不仅阅读起来友好,开发起来也比较简单(2333这个比较关键)。小结一下,JSX本质是React.createElement这个JavaScript调用的语法糖,它允许开发者用较熟悉的类HTML标签语法来创建虚拟DOM,提升了开发效率,也降低了学习成本。
读一读createElement源码
1 | export function createElement(type, config, children) |
这个方法有三个入参,type是节点类型,可以是div、span这样的标准HTML标签字符串,也可以是React组件类型;config是一个对象,以键值对的形式存储了组件的属性;children记录的是子节点、子元素对象。
1 | //propName用于存储元素属性,props用于存储属性的键值对集合 |
看完大家会不会有些失望,原来createElement好像也没做啥哈哈哈,它并没有涉及到真实的DOM。其实它只是接受相对简单的参数然后做一次数据处理,最后调用ReactElement来创建元素。那么我们接下来继续康康ReactElement的源码。
读一读ReactElement源码,认识一下虚拟DOM
1 | //通过React.createElement中调用ReactElement方法我们能得知ReactElement的入参有哪些 |
我们可以发现,ReactElement的逻辑也较为简单,它只是按一定规范组装了一个element对象,通过React.createElement最终返回到了开发者。我们平常去打印一个React元素,就会发现它是一个标准的ReactElement对象实例,如图所示。
这个 ReactElement 对象实例,本质上是以 JavaScript 对象形式存在的对 DOM 的描述,也就是大家常说的虚拟Dom。既然是虚拟的,那它离页面的真实DOM还有一定距离,最终是由ReactDom.render方法来填补的。这个方法可以传入三个参数,需要渲染的元素element,元素挂载的目标容器container也就是真实的DOM节点,以及可选参数回调函数。