JSX深入詳解

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的語法格式,而不是說JSXhtml的補充或拓展。

接下來說說註釋,在以往的項目裏中,沒有提到註釋,但在代碼編寫中,註釋是很重要的組成部分。JSX中的註釋跟普通的javascript註釋稍微有些不同,如果我們的註釋夾雜在標籤之間,那麼我們需要使用大括號把註釋的內容包起來,例如: 

ReactDOM.render(
	<div className="main">
		<p class="content">Hello</p> 
		{/* this is a comment*/} 
		<Label/>
	</div>, 
	document.querySelector("container") 
}

"this is comment" 就是註釋內容,但由於它夾雜在標籤pLabel之間,所以它需要使用一個大括號包圍起來。如果註釋是落在標籤裏面的話,大括號就可以省掉了,例 : 

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是不可能做到的。 







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章