JSX 即 JavaScript XML, 是Facebook 團隊提出的一種在react組件內部構建標籤的類XML 語法。可以在 JavaScript 的代碼直接中使用 HTML 標籤來編寫 JavaScript 對象。這種語法方案需要編譯轉換成真實可用的 JavaScript 代碼。 react在不使用JSX的情況下一樣可以工作,但是Facebook團隊推薦在react使用JSX語法,那麼JSX 到底有哪些優勢呢?
一、使用JSX的優勢
1、更加語義化
在react中,我們可以利用 JavaScript 的語法來書寫 html 標籤,並且還可以定義自己的組件,這些組件可以根據應用場景,使用更加語義化、更加有意義的標籤。這樣我們就避開了複雜了JavaScript邏輯,雖然最後都會轉換爲JavaScript,但是隻要熟悉html的設計師以及測試產品的質量保證的人員,都能輕鬆的閱讀組件代碼。
2、更加直觀
在react中,我們可以將代碼分成一個一個組件,每一個組件負責一個功能。通過對各種組件的組合引用,可以構成一個大項目。
例如我們需要創建一個Divider 組件。我們注意到在函數作用域內,使用JSX 語法的版本與使用原生JavaScript 相比,其標籤的意圖變得更加直觀,可讀性也更高。
以下是原生JavaScript版本:
// v0.11
render: function () {
return React.DOM.div({className:"divider"},
"Label Text",
React. DOM.hr()
);
}
以下是使用JSX的版本:
render: function () {
return <div className="divider">
Label Text<hr />
</div>;
}
通過對比,我們能發現JSX更直觀,也更易懂。
組件化
組件化,也是react的核心,旨在將HTML 標籤以及生成這些標籤的代碼內在地緊密聯繫在一起,封裝成組件,把所有的邏輯和標籤封裝在其中。與之前的將html、 css 和JavaScript分離不同的是,在 react 中,將以組件和單位,所有的html 、css 和JavaScript都封裝在組件中。剛開始,可能會覺得比較彆扭,但是當你真正熟悉了JSX 之後,會覺得 JSX 不僅提供了一個清晰、直觀的方式來描述組件樹,同時還讓你的應用程序更加符合邏輯。
JSX 不僅具有這麼多優勢,而且上手也非常快。下面就具體介紹一下 JSX 的語法使用。
二、JSX語法
JSX 的基本語法規則:遇到 HTML 標籤(以 < 開頭),就用 HTML 規則解析;遇到代碼塊(以 { 開頭),就用 JavaScript 規則解析。JSX 允許直接在模板插入 JavaScript 變量。
1、封裝自己的組件
var HelloMessage = React.createClass({
render: function() {
return <h1>Hello World!</h1>;
}
});
上面我們封裝一個輸出 “Hello World!” 的組件,組件名爲 HelloMessage。
上述代碼中,我們可以封裝多個 html 標籤,但是當有多個標籤時,需要將他們封裝在一個標籤下,也就是說,最終暴露在外面的最外層是一個標籤。如下:
var HelloMessage = React.createClass({
render: function() {
return (<div>
<h1>Hello World!</h1>
<p data-myattribute = "somevalue">welcome to my blog...</p>
</div>
);
}
});
如果我們需要給 HTML 標籤 添加了自定義屬性,添加自定義屬性需要使用 data- 前綴。在上述代碼中,我們給 p 標籤添加了data-myattribute。
另外需要注意的一點是:在 JSX 中,所有的 HTML 標籤 和 自定義的組件 在使用時, 都需要閉合。
2、JavaScript 表達式
用{}包起來的語句會當做JavaScript來解析,加引號就會被當成字符串。
var HelloMessage = React.createClass({
render: function() {
return <h1>Hello World!{1+2}</h1>;
}
});
當碰到{1+2}時,會解析成JavaScript語句,並運行得到結果3,因此最終的組件顯示內容爲Hello World!3
。
在標籤屬性中也能使用JavaScript表達式,例如:
var HelloMessage = React.createClass({
render: function() {
return <h1 className={ 2>1 ? 'classA' : 'classB'}>Hello World!{1+2}</h1>;
}
});
上述代碼中,通過條件判斷來設置h1的樣式,2>1
爲 true , 因此h1的樣式爲classA。 這裏需要說明的是:在JSX中,設置元素的類名時, 不是用 class , 而是用 className。
3、樣式
React 推薦使用內聯樣式。我們可以使用 camelCase (駝峯法)語法來設置內聯樣式。React 會在指定元素數字後自動添加 px 。以下實例演示了爲 h1 元素添加 myStyle 內聯樣式:
var HelloMessage = React.createClass({
render: function() {
var myStyle = {
color:'red',
fontSize:16
};
return <h1 style={myStyle} >Hello World!{1+2}</h1>;
}
});
我們也可以不定義 myStyle 變量,直接在標籤的 style 裏寫樣式,如下:
var HelloMessage = React.createClass({
render: function() {
return <h1 style={{color:'red',fontSize:16}} >Hello World!{1+2}</h1>;
}
});
這兩者顯示的效果是一樣的。
4、數組
JSX 允許在模板中插入數組,數組會自動展開所有成員:
<body>
<div id="example"></div>
<script type="text/babel">
var arr = [
<h1>hello</h1>,
<h2>welcome to my blog....</h2>,
];
ReactDOM.render(
<div>{arr}</div>,
document.getElementById('example')
);
</script>
</body>
效果如下:
如果需要對數組進行遍歷,則可以用map,如下:
var arr = ['sean','Lilei','Tom'];
ReactDOM.render(
<div>
{
arr.map(function(elem, index) {
return <h3 key={index}>Hello, {elem}</h3>;
})
}
</div>,
document.getElementById('example')
);
如果數組內是對象,同樣可以遍歷,然後選擇所需的對象屬性:
var arr = [{'name':'sean'}, {'name':'Lilei'}, {'name':'Tom'}];
ReactDOM.render(
<div>
{
arr.map(function (elem, index) {
return <h3 key={index}>Hello, {elem.name}</h3>;
})
}
</div>,
document.getElementById('example')
);
注意:上面的兩個代碼中,在對數組遍歷時,都設置了 key 屬性,這是因爲如果沒有設置key 屬性時,會出現以下warning:react.js:19287 Warning: Each child in an array or iterator should have a unique "key" prop. Check the top-level render call using <div>. See https://fb.me/react-warning-keys for more information.
。
5、屬性 key
key 是JSX 中特有的屬性,只在JSX 中存在,而非 DOM 屬性。
key 是一個可選的唯一標識符。在程序運行的過程中, 一個組件可能會在組件樹中調整位置,比如當用戶在進行搜索操作時,或者當一個列表中的物品被增加、刪除時。當這些情況發生肘,組件可能並不需要被銷燬並重新創建。
通過給組件設置一個獨一無二的鍵,並確保它在一個渲染週期中保持一致,使得React 能夠更智能地決定應該重用一個組件,還是銷燬並重新創建一個組件,進而提升渲染性能。當兩個已經存在於DOM 中的組件交換位置肘, React 能夠匹配對應的鍵並進行相應的移動,且不需要完全重新渲染DOM 。
6、註釋
在 JSX 中,註釋需要寫在花括號中,實例如下:
var arr = [{'name':'sean'}, {'name':'Lilei'}, {'name':'Tom'}];
ReactDOM.render(
<div>
{/*對數組進行遍歷*/}
{
arr.map(function (elem, index) {
return <h3 key={index}>Hello, {elem.name}</h3>;
})
}
</div>,
document.getElementById('example')
);
7、條件判斷
在 react 中,要想在組件中添加條件判斷似乎是件很困難的事情,因爲if/else 邏輯很難用HTML 標籤來表達。直接往JSX 中加入if 語句會渲染出無效的JavaScript,解決的方法主要有以下四種(當一個加載完成時,給組件添加相應的樣式):
- 使用三目運算符
render: function () {
return <div className={
this.state.isComplete ? 'is-complete' : ''
}>...</div>;
}
- 設置一個變量並在屬性中引用它
getIsComplete: function () {
return this.state.isComplete ? 'is-complete' : '';
},
render: function () {
var isComplete = this.getIsComplete();
return <div className={isComplete}>...</div>;
}
- 將邏輯轉化到函數中
getIsComplete: function () {
return this.state.isComplete ? 'is-complete' : '' ;
},
render: function () {
return <div className={this.getIsComplete()}> . ..</div>;
}
- 使用 && 算符
由於對於null 或false 值React 不會輸出任何內容, 因此你可以使用一個後面跟隨了期望字符串的布爾值來實現條件判斷。如果這個布爾值爲true , 那麼後續的字符串就會被使用。
render: function () {
return <div className={this.state.isComplete && 'is-complete'}>
...
</div>;
}