我第一次接觸JSX是在學習React的時候,當時乍一看語法覺得和js很像,在一看又覺得和HTML很像,後期有了專案經驗之後確定jsx確實和那兩位有關係。下面解釋怎麼個有關係法。
一. React元件的構成?
JSX和React有什麼關係呢?簡單說,JSX就是方便React使檢視層(View層)元件化,承載了HTML構建頁面的職責。這點可以看出React還是和其他Js模板語言有著異曲同工之秒的,不同的是React致力於通過建立和更新虛擬元素來管理整個虛擬DOM的(Virtual DOM)。
那什麼是虛擬元素呢,其實就是真實元素的對應,虛擬元素的建立和更新都是在記憶體中完成的,並不會渲染到真正DOM中。虛擬元素分為虛擬DOM和虛擬元件,對應的也就是原生DOM元素和自定義元件。
接著,從DOM元素和自定義元件來解釋:
1.DOM元素
一個很普通的標籤:
<button class="btn btn-blue">
<em>Confirm</em>
</button>
複製程式碼
上述button標籤包含了元素的型別和屬性,轉換成JSON物件可以更清晰地看見包括元素的型別和屬性,即,該標籤是一個DOM元素:
{
type: 'button',
props: {
className: 'btn btn-blue',
children: {
type: 'em',
props: {
children: 'Confirm'
}
}
}
}
複製程式碼
2.元件元素
上面例項用自定義方法表示為:
const Button = ({color,text}) => {
return (
type: 'button',
props: {
className: `btn btn-${color}`,
children: {
type: 'em',
props: {
children: text
}
}
}
)
}
複製程式碼
該方法用JSON結構描述它為下述,也就是說元件方法的方法名對應了元素的型別,引數對應了元素的屬性,滿足了構造元素的兩大必要條件(元素型別和元素屬性),得出結論:自定義方法也是元素
{
type: Button,
props: {
color: 'blue',
text: 'Confirm'
}
}
複製程式碼
用了兩個例子來說明一件事----無論普通標籤還是一個自定義元件方法,都可以用元素表示。這也是React核心思想之一:因為有公共的表達方法,我們可以讓元素們層層巢狀或混合,這些層層巢狀的元件元素就是所謂的React元件,最終我們可以通過遞迴渲染的方式渲染出一整棵DOM樹。
二. JSX由來
構建一個複雜的React元件(還是一個Button元件吧)
(1).首先定義一個元件元素:
const DanderButton = ({text}) => {
type: Button,
props: {
color: 'blue',
text: text
}
}
複製程式碼
(2).用上面的組建繼續封裝一個新的元件
const DeleteButton = () => {
return (
type: 'div',
props: {
children: [
{
type: 'p',
props: {
children: 'Are you sure?'
}
},{
type: DanderButton,
props: {
children: 'Confirm'
}
},{
type: 'Button',
props: {
color: 'blue',
children: 'Cancel'
}
}
]
}
)
}
複製程式碼
這是一個比較簡單的React元件的巢狀,DeleteButton元件清晰地表達了一個功能模組(最外側div)、一段提示語、一個表示確認的按鈕、一個表示取消的按鈕,這麼簡單的功能都已經感覺到很繁瑣了,那麼如果用這種方式去程式設計,感覺會很糟糕,這時讓我們想起了用HTML寫頁面的暢快,JSX寫法應運而生。
同樣是上面的功能,看看JSX是怎麼實現的:
const DeleteButton () => (
<div>
<p>Are you sure?</p>
<DanderButton> Confirm </DanderButton>
<Buton color="blue">Cancel</Buutton>
</div>
);
複製程式碼
可見:JSX是將HTML語法加入到Javascript程式碼中,再通過翻譯器轉換成純Javascript後讓瀏覽器執行。實際開發中打包階段都已將編譯成純Javascript程式碼,所以不會帶來任何副作用,反而讓程式碼更加直觀並且易於維護。
現階段為JSX語法解析的編譯器基本上都在用Babel
上述程式碼可以被Babel解析成React可以執行的程式碼
var DeleteButton = function DeleteButton () {
return React.createElement(
'div',
null,
React.createElement(
...
),
React.createElement(
...
),
React.createElement(
...
)
)
}
複製程式碼
可以看出,建立元素時候除了使用React.createElement建立之外,其結構與JSON一樣。
總結:
綜合來看,JSX實質上就是為了方便React將View層元件化,通過將HTMl語法加到Javascript程式碼中,以承擔構建頁面的職責。