這一系列的文章我會盡我所能,用扁平化的思惟,和合理順序來幫助你們分析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是怎麼回事,他的背後到底都作了些啥子東西。