这一系列的文章我会尽我所能,用扁平化的思惟,和合理顺序来帮助你们分析React究竟是怎么玩的,但仍要假定读者具有最基础的开发经验与知识储备,具体的条件以下:javascript
只要能知足上述的条件,那么这个系列就是适合你阅读的。html
你们可能都知道,使用create-react-app建立出的项目能够直接在js文件里书写react组件,或者jsx代码。java
好比:react
const com = <div>12332</div>
console.log(com);
复制代码
像上面的代码,通过create-react-app自带的webpack编译事后,能够成功在浏览器中执行。当咱们把这段代码复制出到浏览器窗口里,咱们会发现控制台报错了。webpack
很简单,由于原生js并不支持jsx语法,也就是说,标准的js运行环境中,是不容许写html标签的,js中没有这样的语法。之因此代码跑的起来,是由于通过了babel的编译。web
在当下,jsx代码多数是由@babel/preset-react转译而成。设计模式
咱们能够打开babel的playground查看一下背后都发生了些什么。数组
能够看到,实际上在浏览器中的跑的代码实际上是以下一段:浏览器
"use strict";
var com = React.createElement("div", null, "123123");
复制代码
能够这样试一下,js中的代码<div>123123</div>
其实相等于React.createElement("div", null, "123123")
。bash
createElement这个方法,有两个必填参数,和无限剩余可选参数,第一个参数是元素的名称(字符串或者是其余类型),或者是其余类型(后面会讲),第二个参数就是你们熟知的props。
咱们如今给div加个属性上去
const com = <div id="123">123123</div>
复制代码
编译后
var com = React.createElement("div", {
id: "123"
}, "123123");
复制代码
能够发现,第二个参数在没有任何prop属性的状况下,是个null,可只要传入了任意一个props,就会变成一个plainObject,好比上面的{id:"123"}
。
至于第二个参数之后,参数的数量是零到无限的,就是该元素的直系children有多少个,后续就会有多少个参数,也是createElement方法的嵌套,咱们再看下嵌套下的状况。
const com = <div id="123"><span>1</span><span>2</span></div>
复制代码
var com = React.createElement("div",
{
id: "123"
},
React.createElement("span", null, "1"),
React.createElement("span", null, "2")
);
复制代码
看的出,div元素下的两个span也被转换成了createElement而且被依次排列在了第二个参数后面。
这就是babel之力,平时咱们写的大部分标签语法,实际最后都转成了这个样子。createElement应该是最高频被调用的内置方法了。
function AComp() {
return <div>123</div>
}
const a = <AComp/>
复制代码
"use strict";
function AComp() {
return React.createElement("div", null, "123");
}
var a = React.createElement(AComp, null);
复制代码
咱们能够看到<Acomp>
被转换成了React.createElement(AComp, null);
。这个时候咱们传入的第一个参数不是字符串了,而是使用的函数组件自己。
把AComp从函数改为类组件,也会有相同的结果,具体的逻辑判断,会在react-dom中体现,这个咱们后面再说。
那咱们如今把AComp改为小写的名字,改成acomp。
function acomp() { return <div />}
const a = <acomp/>
复制代码
"use strict";
function acomp() {
return React.createElement("div", null);
}
// 第一个参数是字符串"acomp",而非acomp函数自己
var a = React.createElement("acomp", null);
复制代码
babel编译后之后能够看得出,createElement的第一个参数并非acomp这个函数自己了,而是一个字符串,preset-react会把全部小写开头的标签,转换为字符串,它人为小写开头的元素声明,都是原生dom元素,好比div。而大写开头的就是函数组件或者类组件。
而当咱们把组件写成小写调用后,就会没法调用确切想调用的组件。
搞懂了jsx和Babel是咋回过后,下一节咱们来分析createElement是怎么回事,他的背后到底都作了些啥子东西。