為什么需要JSX
JSX 是 Facebook 團隊提出的一個語法方案,可以在 JavaScript 的代碼直接中使用 HTML 標簽來編寫 JavaScript 對象肴熏。其使用的是 XML-like
語法鲁猩,這種語法方案需要通過 JSXTransformer
來進行編譯轉(zhuǎn)換成真實可用的 JavaScript 代碼(React 官方已經(jīng)推薦使用 babel
來代替)盏缤。
React 是基于組件的開發(fā)思想,React 認為一個組件可以是一個完全獨立的沒有任何其他依賴的模塊文件古程。一個組件中可以有自己的樣式(Inline Style)和結(jié)構(gòu)(JSX編寫的HTML)煎殷。
在 React 和 JSX 之前屯伞,一個組件如果要包含 HTML 結(jié)構(gòu)將面臨如下幾個問題:
組件的 HTML 直接寫在頁面中,那么組件的結(jié)構(gòu)和行為是分離的豪直;
組件的 HTML 直接用字符串的形勢插入到 JavaScript 代碼中劣摇,那么就會出現(xiàn)一大段的字符串拼接,開發(fā)人員需要很小心的確保字符串拼接時沒有因為少了一個符號而導(dǎo)致整個代碼無法運行弓乙;
使用 MVC
分層的思想末融,引入模板引擎,那么該如何引入模板文件的片段呢暇韧;
JSX 很好的解決了這些問題勾习。
基本語法
使用 JSX 來創(chuàng)建一個 HTML 標簽,首字母小寫:
<pre>
var link = <a href="xxx">Hello World!</a>
</pre>
相當(dāng)于調(diào)用了 React.createElement
方法:
<pre>
var link = React.createElement('a', {href: 'xxx'}, 'Hello World!')
</pre>
使用 JSX 來創(chuàng)建一個 Component懈玻,首字母大寫:
<pre>
var HelloWorld = <HelloWorld foo="bar"></HelloWorld>
</pre>
首字母的大小寫有嚴格的區(qū)分巧婶,這樣 JSX 可以很簡單的通過區(qū)分首字母是小寫還是大寫來判斷轉(zhuǎn)換的是 HTML 標簽還是自定義的 Component。
JSX 標簽的標簽都需要有完整的結(jié)束符號涂乌,否則編譯會報錯艺栈。
<pre>
<div></div>
<input type="text"/>
</pre>
變量和邏輯
JSX 中可以通過 {xxx}
來插入一個 JavaScript 變量:
<pre>
var name = 'xiao ming';
<a href="xxx">Hello {name}!</a>
</pre>
沒錯,HTML 語法就是這樣和 JavaScript 語法無縫的結(jié)合湾盒!
如果要在 JSX 中插入一段 JavaScript 代碼湿右,那么一次只能插入一個一次就能執(zhí)行完的語句。
<pre>
var link = <a href="xxx">Hello {if (conditions) {'xiao ming'}}!</a>
</pre>
上面的代碼編譯后會是這樣的:
<pre>
var link = React.createElement( 'a', {href: 'xxx'}, if (conditions) {'xiao ming'})
</pre>
編譯后可以看到明顯存在語法錯誤罚勾,可以使用三元運算符來將條件判斷語句簡化成一個語句:
<pre>
var link = <a href="xxx">Hello {conditions ? 'xiao ming' : ''}!</a>
</pre>
多行語句和根節(jié)點
無論你的 JSX 代碼有多長毅人,每一段代碼都只能有一個根節(jié)點,否則編譯通不過尖殃,因為 React 需要確保一個組件只能有一個根節(jié)點丈莺。
<pre>
// 錯誤的寫法
var btnBox = (
<button>Click me</button>
<p>hello world!</p>
);
// 正確的寫法
var btnBox = (
<div>
<button>Click me</button>
<p>hello world!</p>
</div>
);
</pre>
如果想在 JSX 中添加注釋,需要使用多行注釋的語法并確保其包裹在 {} 中分衫。
<pre>
<div>
<h3> title </h3>
{/*<p>text</p>/*}
</div>
</pre>
關(guān)鍵字沖突
因為 JSX 是直接將 HTML 寫在 JavaScript 代碼中场刑,如果在 HTML 中有的屬性中有 JavaScript 的關(guān)鍵字,必須進行轉(zhuǎn)換蚪战,轉(zhuǎn)換規(guī)則和在 JavaScript 中使用 DOM 的 property 一樣牵现。如 class 需轉(zhuǎn)換成className,for 要轉(zhuǎn)換成 htmlFor邀桑,還有其他的關(guān)鍵字這里不做一一列舉瞎疼。
false in JSX
false 在 JSX 中,會有不同的作用壁畸。
<pre>
<div id={false}>
<input type="text" name="name" value={false} />
<button type="button" name="button" disabled={false}>hello</button>
<p>{false}</p>
</div>
</pre>
id={false} 和 value={false} 都換轉(zhuǎn)換成字符串 false贼急,disabled={false} 是設(shè)置 disabled屬性為 false茅茂,<p>{false}</p> 表示該 p 標簽沒有子元素
Inline Style
上面提到過 React 希望一個組件中可以是獨立的,可以將樣式直接通過 JavaScript 的對象插入到 JSX 中太抓,這樣就可以給一個組件定義樣式了空闲。
<pre>
var paraStyle = {
color: '#fff',
fontSize: '14px'
};
var para = (
<p style={paraStyle}></p>
);
</pre>
在定義樣式的時候,對象的 key 就是樣式的屬性走敌,屬性中如果有中劃線碴倾,需將其換成駝峰式value 就是對應(yīng)的屬性值。對于一些復(fù)雜的偽類選擇器掉丽,以及其他的一些高級的 CSS 特性跌榔,有相應(yīng)的庫可以對其支持。
將樣式通過內(nèi)聯(lián)的形式寫在組件內(nèi)部捶障,雖然有違分離原則僧须,但是其確實解決了因為分離帶來的組件獨立性的問題,雖然是反模式化的项炼,但確確實實解決了一個痛點担平。
命名空間
JSX 中還可以支持組件的命名空間,可以讓組件的層次更清晰芥挣,更語義化驱闷。
<pre>
var Form = React.createClass({ ... });
Form.Row = React.createClass({ ... });
Form.Label = React.createClass({ ... });
Form.Input = React.createClass({ ... });
var App = (
<Form>
<Form.Row>
<Form.Label />
<Form.Input />
</Form.Row>
</Form>
);
</pre>
代碼風(fēng)格建議
為了代碼有更好的可讀性,無論是單行語句還是多行語句空免,都建議使用 () 來包裹 JSX 語句空另。在JSX 中插入 JavaScript 語句的時候盡量不要嵌套太長的三目運算符,JSX 本身就是為了開發(fā)更簡便和更好的維護性蹋砚。如果把 JSX 也寫成一坨一坨可讀性很差的代碼扼菠,實在太不應(yīng)該了。
原載于:雨夜帶刀’s Blog本文鏈接:http://stylechen.com/react-jsx.html
如需轉(zhuǎn)載請以鏈接形式注明原載或原文地址坝咐。