序
学习源码的目的是为了更好得解决问题,越接近本质就越能解决复杂问题。同时读 React 源码是在汲取世界上最顶尖的前端工程师的养分,提升编码水平。
目前主要学习材料是慕课网《React源码深度解析 高级前端工程师必备技能》课程,React 源码解析小册。水平有限,欢迎讨论。
1. JSX 与 关注点分离
JSX 简介,以上是 React 官方对 JSX 的介绍。
使用 React 最常用的就是使用 JSX 语法了。JSX 让 HTML 标签以及生成这些标签的代码内在得紧密联系在一起,于是我们不需要把单个组件拆分成视图和模板文件,反而是为每一个小的关注点创造一个独立的组件,并且把所有的逻辑和标签封装在其中。
这种设计原则叫做 “关注点分离”,目的是为了更有效得理解,设计和管理有许多功能互相依存的复杂系统,以便功能可以重用,独立于其他功能进行优化。
举个例子:配电将炉子保持在一个电路,而灯光则保持在另一个电路上,这样炉子的超载就不会影响灯光。
当然JSX 的优点还有很多,包括让代码更加直观,对代码的抽象能力……
2. JSX 是如何运行的?
<div id="id">stone</div>
// 以下是 JSX 代码 用 Babel 转化出来的原生 JavaScript 代码。
"use strict";
/*#__PURE__*/
React.createElement("div", {
id: "id"
}, "stone");
我们可以看到 JSX 语法的实质上是用 React 的 API —— createElement 创造节点。
它有三个参数,第 1 个参数是节点的类型,如果是原生的标签会是字符串;第 2 个参数是一个对象,包含了所有节点上的属性;第 3 个参数是节点内的内容。
再看一个复杂的例子。
function Comp() {
return <a>123</a>
}
<Comp id="id">
<span></span>
<span></span>
<div>stone</div>
</Comp>
// 以下是 JSX 代码用 Babel 转化出来的原生 JavaScript 代码。
"use strict";
function Comp() {
return /*#__PURE__*/React.createElement("a", null, "123");
}
/*#__PURE__*/
React.createElement(Comp, {
id: "id"
},
/*#__PURE__*/React.createElement("span", null),
/*#__PURE__*/React.createElement("span", null),
/*#__PURE__*/React.createElement("div", null, "stone"));
如上图所示,组件在转化为原生 JavaScript 后,名称变成了一个变量,同时组件内部的多个标签转化为了,第 4,第 5,第 6个参数。
function stone() {
return <a>Stone</a>
}
<stone id="id">
<span></span>
<span></span>
<div>stone</div>
</stone>
// 以下是 JSX 代码用 Babel 转化出来的原生 JavaScript 代码。
"use strict";
function stone() {
return /*#__PURE__*/React.createElement("a", null, "Stone");
}
/*#__PURE__*/
React.createElement("stone", {
id: "id"
}, /*#__PURE__*/React.createElement("span", null), /*#__PURE__*/React.createElement("span", null), /*#__PURE__*/React.createElement("div", null, "stone"));
要注意的是,如果组件名称是小写会被转化成 字符串,从而在运行时发生错误。
下篇
createElement 源码分析