React-JSX詳解
一、
1、JSX:即JavaScript XML——一種在React組建內部構建標籤的類XML語法。(增強React程式元件的可讀性);
2、使用動態值:
JSX將兩個花括號:{}渲染成動態值,花括號指明瞭一個JavaScript上下文環境——或括號內的任何東西都會進行求值,得到的結果會被渲染為標籤中的若干節點。
對於簡單值,比如文字或者數字,你可以直接引用對應的變數,例如:
var text=‘Questions’;
<h2>{text}</h2>
對於更復雜的邏輯,可以更傾向於將其轉換成一個函式來求值,例如:
function()dateToString(d){
return
d.getFullYear();
d.getMonth()+1;
d.getDate()
].join('-');
};
<h2>{dateToString(newDate())}</h2>
React通過陣列中的每個元素渲染為一個節點的方式對陣列進行自動求值:
var text=[‘hello','hello'];
<h2>{text}</h2>
//<h2>helloworld</h2>
3、子節點
比起簡單的值,我們通常希望渲染一些更復雜的資料,比如說,可以把陣列中的所有資料渲染成若干個<li>元素,就要涉及到子節點了:
var Divider =React.createClass({
render:function(){
return(
<div className="divider">
<h2>{this.props.children}<h2>
</div>
)
}
});
<Divider>Questions</Divider>
React將開始標籤和結束標籤中所有的子節點儲存在一個名為this.props.children的元件屬性中。而以上例子中this.props.children==["Questions"];
4、JSX
1)屬性設定
var surveyQuestionId =this.props.id;
var classes ="some-class-name";
...
<div id = {surveyQuestionId}className={classes}>...</div>
對於屬性的設定和HTML很相似,注意設定class的方式不是class而是className;對於更復雜的情景可以把屬性設定為一個函式呼叫返回的結果;
<divid={this.getSurveyId()}>...</div>
React每渲染一個元件時,知道哪個的變數和函式會被求值,而總重生成的DOM結構反映出這個新的狀態。
2)條件判斷
在React中元件的HTML標籤和生成這些標籤的程式碼內在的緊密聯絡在一起,這意味著可以利用JavaScript強大的功能,例如迴圈和條件判斷。
要是在元件中新增條件判斷似乎是很困難的事情,因為if/else邏輯很難用HMTL標籤來表達。直接往JSX中加入if語句會渲染出無效的JavaScript。
解決辦法:
使用三目運算子,設定一個變數並在屬性中引用它,將邏輯轉化到函式中,使用$$運算子,以下演示:
使用三目運算子:
render:function(){
return <divclassName={
this.state.isComplete ?'is-complete':‘‘
}>...</div>
}
雖然對於文字來說三目運算子可以正常執行,但是如果想要在其他情況下很好地應用ReactComponent,三目運算子就可能顯得笨重又麻煩了。對於這些情況最好使用以下方法:
使用變數:
getIsComplete:function(){
return this.state.isComplete ?'is-complete' : ' ';
},
render:function(){
var isComplete= this.getIsComplete();
return <divclassName={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 <divclassName={this.stae.isComplete && 'is-complete'}></div>
}
5、非DOM屬性
1)下面的特殊屬性只有在JSX中存在:key、ref、dangerouslySetInnerHTML
鍵(key):
可以是一個可選的唯一識別符號。在程式執行的過程中,一個元件可能會在元件樹中調整位置,比如當前使用者在進行所有操作時,或者當一個列表中的物品被增加、刪除時。這種情況下元件可能不需要被銷燬並重新建立。
通過給元件設定唯一的key。確保渲染週期內保持一致,使React能夠更智慧的決定應該重用一個元件,還是銷燬並重新建立一個元件,今兒提升渲染的效能,當兩個已經存在DoM中的組建交換位置時,可以不用重新渲染DOM而是移動。
引用(ref):
ref允許負父元件在render方法之外保持對子元件的一個引用。
在jSX中,可以通過屬性中設定期望的引用名定義一個引用。例如:
render:function(){
return <div><input ref='myInput'.../></dib>
}
然後,你就可以在元件中的任何地方使用this.refs.myInput獲取這個引用了。通過或者這個物件唄成為支援例項。並不是真的DOM,而是REact在需要的是有用來穿件DOM的一個描述物件。可以使用this.refs.myInput.getDOMNode()訪問真實的DOM節點。
設定原始的HTML:
dangerouslySetInnerHTML——有時候需要將HTML內容設定為字串,尤其是使用通過字串操作DOM的第三方庫時,為了提升React的互操作性,這個屬性允許你使用HTML字串,然而如果你可以避免使用的話那就儘量不要使用。要使用這個作用要把字串設定到逐漸為html_的物件裡,像這樣:
render:function(){
var htmlString={
_html:"<span>an htmlstring</span>“
};
return <div dangerouslySetInnerHTML={htmString}</div>
}
6、事件
1)在所有瀏覽器中,時間名已經被規範化並同意用駝峰形式表示。例如,change變成了onChange,click變成了onClick,在JSX中,捕獲一個事件就像是給元件的方法設定一個屬性一樣簡單。
handleClick:funcition(event){............},
render:function(){
rerurn <divonClick={this.handleClick}>...</div>
}
...
注意,React自動綁定了組建所有方法的作用域,因此你永遠都不需要手動繫結。
handleClick:function(event){.....}
render:function(){
//反模式——在React中手動給元件例項繫結
//函式的作用域是沒有必要的
return <div onClick ={this.handleClick.bind(this)}></div>
}
7、註釋
1)JSX本質上就是JavaScript,因此你可以在標籤內新增原生的JavaScript註釋,註釋可以用以下兩種方式新增:當作一個元素的子節點、內聯在元素的屬性中。
2)做為子節點
子節點形式的註釋只需要簡單的包裹在花括號內即可,並可以跨多行。
例如:
{/*內容。。。。。。*/}
3)作為內聯屬性
/*
內容
內容
*/
或者採用常用的 //來做單行註釋
4)特殊屬性
由於JSX會轉化成原生的JavaScript函式因此有一些關鍵詞我們不可以用的:如for和class
要給表單裡的變遷新增for屬性需要使用htmlFor,要渲染一個自定義的class需要使用className。可以通過elem.className獲取元素的class。
8、樣式
React把內聯樣式規範化為了駝峰形式,與JavaScript中DOM的style屬性一致。要新增自定義的樣式屬性,只需簡單地把駝峰形式的屬性名及期望的CSS值拼裝為物件即可。
varstyles={
borderColor:“#999",
borderThickness:“1px”
};
React。renderComponent(<div style={styles}>...</div>,node);
9、沒有JSX的React
所有的JSX標籤最後都會被轉換成原生的JavaScript,因此React並不是必要的,但是JSX的確減少了一部分複雜性。
React.createElement('div');
React.DOM.div();
然而對於自定義元件來說必須為組建類建立一個工廠。