JSX是一種類似於html標籤組合的語法對象,JSX實例如下:
var Card = React.createClass({
render: function() {
return (
<div>
<Square color={this.props.color}/>
<Label color={this.props.color}/>
</div>
)
}
})
return 返回的那一段標籤代碼,我們就稱之爲JSX. 它跟html很像,但又不是html, 因爲標準html中根本不存在Square, Label 這種標籤。因此,如果我們直接把這段標籤代碼提交給瀏覽器,瀏覽器是識別不了的。但爲何最終這段代碼被瀏覽器加載後能夠正確的發揮作用呢?這就要依賴於React 提供的Babel組件了,你可以認爲,Babel 是一個編譯器,他把瀏覽器識別不了的JSX標籤代碼,編譯成瀏覽器能識別的javascript代碼。
那麼這段JSX代碼被Babel翻譯後會變成什麼樣子呢,它們經過轉換後會變成如下形式:
return React.createElement("div",
React.createElement(Square,{color:this.props.color}),
React.createElement(Label,{color:this.props.color})
)
React 本身是 個js 對象,通過createElement返回的也是 個js 對象。也就是說,儘管我們寫代碼時,需要依賴於 個JSX的概念,但當瀏覽 加載代碼前,Babel這個編譯 先把代碼進 次轉換,然後再把轉換後的代碼提交給瀏覽 執行,因此瀏覽 運 的代碼是 存在JSX這種形式的。
由於存在這種隱形的轉換過程,因此在使 JSX的時候,有不少我們需要注意的地方。 先需要注意的是JSX對象必須要有一個根節點, 如以下代碼是錯誤的:
ReactDOM. render(
<Letter>A</Letter>
<Letter>E</Letter>
<Letter>I</Letter>
<Letter>O</Letter>
,
document.querySelector("container")
);
Letter是一個React組件,上面的代碼把一個React組件並排放在一起,上面的代碼如果經過Babel編譯轉換的話,會變成以下形式:ReactDOM.render( React.createElement(Letter, null, "A"),
React.createElement(Letter, null, "E"),
React.createElement(Letter, null, "I"),
React.createElement(Letter, null, "O"),
docuyment.querySelector("container"))
render 函數只接受兩個參數,但是上面代碼轉義後,render被傳入多個參數,因此就要導致錯誤,所以正確的做法是,要在多個並列的React組件之上加上一個根元素。ReactDOM. render(
<div>
<Letter>A</Letter>
<Letter>E</Letter>
<Letter>I</Letter>
<Letter>O</Letter>
</div>,
document.querySelector("container")
);
上面代碼被babel轉義之後形式如下:
ReactDOM.render(
React.createElement(div, null,
React.createElement(Letter, null, "A"),
React.createElement(Letter, null, "E"),
React.createElement(Letter, null, "I"),
React.createElement(Letter, null, "O"),
),
docuyment.querySelector("container")
)
也就是說render函數被調用是,傳給它的只有兩個參數。第二點需要注意的是,不要直接在JSX中使 css代碼。例如下面的代碼就是錯誤的:
<div style="font-family: sans-serif">
<p>Hello</p>
</div>
如果想要在JSX中設置界面顯示屬性,必須把這些屬性作爲一個style對象的屬性來設置,所以想要把界面顯示邏輯寫到React 組件時,必須先把對應的css屬性轉換成json對象的屬性,然後通過style關鍵字,把這些屬性設置到JSX中,這樣React才能正確解讀, 如如下代碼:
var Letter = React.createClass({ render: function() {
var letterStyle = {
padding: 10,
margin: 10,
backgroundColor: this.props.bgcolor, display: "#333",
fontFamily: "monospace",
fontSize: "32",
textAlign = "center"
};
return (
<div style={letterStyle}>{this.props.children} </div>
) }
})
需要注意的是,style對象裏面的屬性跟css的屬性是一一對應的,如果css的屬性是 個連接詞,也就是兩個單詞間使 "-"來鏈接,那麼在style 對象 ,需要把它們轉換成駱駝格式,此外如果在css中,屬性的值對應的是字符串,那麼在style對象中,需要轉換成雙引號包含對應的字符 。
在html的標籤中,可以通過class關鍵字來設置該對象的類屬性。但在React裏,class是有特殊用途的關鍵字,所以在JSX中,想要給某個標籤添加class屬性時,必須使用關鍵字className, 而不能使用class.
JSX代碼片段正是因爲跟html有這些區別,所以我們說JSX支 持類html的語法格式,而不是說JSX是html的補充或拓展。
接下來說說註釋,在以往的項目裏中,沒有提到註釋,但在代碼編寫中,註釋是很重要的組成部分。JSX中的註釋跟普通的javascript註釋稍微有些不同,如果我們的註釋夾雜在標籤之間,那麼我們需要使用大括號把註釋的內容包起來,例如:
ReactDOM.render(
<div className="main">
<p class="content">Hello</p>
{/* this is a comment*/}
<Label/>
</div>,
document.querySelector("container")
}
"this is comment" 就是註釋內容,但由於它夾雜在標籤p和Label之間,所以它需要使用一個大括號包圍起來。如果註釋是落在標籤裏面的話,大括號就可以省掉了,例 :
ReactDOM.render({
<div>
<Label
/* this is comment in label*/
className="label" />
</div>
});
注意大小寫! 在JSX中,如果標籤屬於html標準控件,那麼該標籤的名字必須小寫,如果標籤屬於React組件,那麼組件變 名稱首字母必須大寫,要不然React就不會加載對應的控件。JSX只包含html標準控件,標籤的名稱都是小寫 ,JSX中包含 React控件的話,那麼控件首字符必須大寫 。
組件可以作爲JS變量在代碼中隨處引用。例
var myComponent = <MyComponent color="red"/>
ReactDOM.render(
<div>
{myComponent}
</div>,
document.querySelector("container")
)
我們在一段JSX代碼中引用了一個組件,這段JSX代碼可以賦值給一個變量,這個變量以後就可以使用在其他JSX代碼中。
結論:
JSX不是HTML.它看起來和用起來跟html很像,但它經過React Babael組件的轉義後,會變成一段js代碼。也就是說JSX本身其實具備着運用業務邏輯的功能,這點html是不可能做到的。