¸1.认识JSX
1.1JSX是什么?
JSX是一种JavaScript的语法扩展(eXtension),也在很多地方称之为JavaScript XML,因为看起就是一段XML语法;
它用于描述我们的UI界面,并且其完成可以和JavaScript融合在一起使用;
它不同于Vue中的模块语法,你不需要专门学习模块语法中的一些指令(比如v-for、v-if、v-else、v-bind);
1.2 为什么React选择了JSX?
React认为渲染逻辑本质上与其他UI逻辑存在内在耦合
比如UI需要绑定事件(button、a原生等等);
比如UI中需要展示数据状态,在某些状态发生改变时,又需要改变UI;
他们之间是密不可分,所以React没有将标记分离到不同的文件中,而是将它们组合到了一起,这个地方就是组件(Component);
当然,后面我们还是会继续学习更多组件相关的东西;
在这里,我们只需要知道,JSX其实是嵌入到JavaScript中的一种结构语法;
2.jsx事件监听
2.1通过onClick直接绑定函数(方式一)
通过直接绑定的方式可以调用‘btnClick’函数,但是会有一个弊端,无法通过this调用组件内的状态属性。原因是onClick是通过React内部调用,没有绑定this,所以‘btnClick’函数内的this指向‘undefine’。
2.2 通过显示绑定方式调用(方式二)
通过bind函数主动绑定this可以解决btnClick内部this指向问题,但是方式二的弊端是有大量的重复代码,必须需要调用this.XXX.bind(this),并且传参也不方便。
2.3使用 ES6 class fields 语法(方式三)
你会发现我这里将btnClick的定义变成了一种赋值语句:
这是ES6中给类定义属性的方法,称之为class fields语法;
因为这里我们赋值时,使用了箭头函数,所以在当前函数中的this会去上一个作用域中查找;
而上一个作用域中的this就是当前的对象;
2.4 事件监听时传入箭头函数(推荐)
因为 onClick 中要求我们传入一个函数,那么我们可以直接定义一个箭头函数传入:
传入的箭头函数的函数体是我们需要执行的代码,我们直接执行 this.btnClick();
this.btnClick()中通过this来指定会进行隐式绑定,最终this也是正确的;
3.JSX转换本质
实际上,jsx 仅仅只是 React.createElement(component, props, ...children) 函数的语法糖。
所有的jsx最终都会被转换成React.createElement的函数调用。
React.createElement在源码的什么位置呢?
createElement需要传递三个参数:
参数一:type
当前ReactElement的类型;
如果是标签元素,那么就使用字符串表示 “div”;
如果是组件元素,那么就直接使用组件的名称;
参数二:config
所有jsx中的属性都在config中以对象的属性和值的形式存储
参数三:children
存放在标签中的内容,以children数组的方式进行存储;
当然,如果是多个元素呢?React内部有对它们进行处理,处理的源码在下方
对children进行的处理:
从第二个参数开始,将其他所有的参数,放到props对象的children中
4. 虚拟DOM
我们通过 React.createElement 最终创建出来一个 ReactElement对象:
这个ReactElement对象是什么作用呢?React为什么要创建它呢?
原因是React利用ReactElement对象组成了一个JavaScript的对象树;
JavaScript的对象树就是大名鼎鼎的虚拟DOM(Virtual DOM);
如何查看ReactElement的树结构呢?
我们可以将之前的jsx返回结果进行打印;
注意下面代码中我打jsx的打印;
打印结果,在浏览器中查看:
而ReactElement最终形成的树结构就是Virtual DOM。
3.1为什么采用虚拟DOM
为什么要采用虚拟DOM,而不是直接修改真实的DOM呢?
很难跟踪状态发生的改变:原有的开发模式,我们很难跟踪到状态发生的改变,不方便针对我们应用程序进行调试;
操作真实DOM性能较低:传统的开发模式会进行频繁的DOM操作,而这一的做法性能非常的低;
主要原因:DOM操作性能非常低:
首先,document.createElement本身创建出来的就是一个非常复杂的对象;
https://developer.mozilla.org/zh-CN/docs/Web/API/Document/createElement
其次,DOM操作会引起浏览器的回流和重绘,所以在开发中应该避免频繁的DOM操作;
虚拟DOM帮助我们从命令式编程转到了声明式编程的模式
React官方的说法:Virtual DOM 是一种编程理念。
在这个理念中,UI以一种理想化或者说虚拟化的方式保存在内存中,并且它是一个相对简单的JavaScript对象,我们可以通过ReactDOM.render让 虚拟DOM 和 真实DOM同步起来,这个过程中叫做协调(Reconciliation);
这种编程的方式赋予了React声明式的API:你只需要告诉React希望让UI是什么状态,React来确保DOM和这些状态是匹配的。
你不需要直接进行DOM操作,只可以从手动更改DOM、属性操作、事件处理中解放出来;