1 簡介 jsx(JavaScript XML),即可拓展的JavaScript,是react定義的一種類似於XML的js擴展語法:JS+XML。它本質上是React.createElement(type,config,...children)的語法糖,主要用於創建React元素,生成虛擬DOM 2 ...
1 簡介
jsx(JavaScript XML),即可拓展的JavaScript,是react定義的一種類似於XML的js擴展語法:JS+XML。它本質上是React.createElement(type,config,...children)的語法糖,主要用於創建React元素,生成虛擬DOM
2 使用jsx
可以使用react腳手架或者引入react與babel相關腳本來體驗jsx。
這裡主要介紹一下後者如何使用
3 jsx語法規則
jsx包括xml格式的標簽和jsx表達式{},下麵從這兩個角度來介紹jsx的語法規則
標簽規則
- 根標簽單一且閉合,否則拋出異常
- 標簽類名使用className而非class,內聯樣式的屬性名採用小駝峰形式命名
const FC = () => (
<h1 className="font-red">
hello react
<span style={{ color: 'blue' }} onClick={() => { alert('click span') }}>inner text</span>
</h1>
)
- 標簽屬性都可以使用jsx表達式{},只有字元串可以省略大括弧
<h1 className="font-red">
hello react
</h1>
jsx表達式規則
- {}中必須返回一個值
- 基於1,流程式控制制與迴圈語句語句如if、for是不允許的,因為他們預設沒有返回值,而邏輯運算符如&&、||、三元表達式是允許的,函數也是允許的,因為它們一定會返回一個值。因此jsx中做邏輯判斷的時候考慮使用後者。
- 基於2,如果一定要使用if、for,考慮在jsx表達式中使用IIFE
<input type="text" value={((type)=>{
if(type === 1){
return 'one'
}else if(type === 2){
return 'two'
}else{
return ''
}
})(type)} />
- 對於falsy值,0會被正常渲染到頁面,而false,true,null,undefined不會。如果一定要渲染它們,請先轉換成字元串。
// 比如下麵這段代碼會在頁面上顯示一個不符合期望的0
const FC2 = ({arr}) => <span>{arr.length && arr.join()}</span>
ReactDOM.render(<FC2 arr={[]} />, document.getElementById('app'))
4 jsx優缺點
4.1 優點
js語法在運行時靈活的特性
基於js語法拓展,jsx具有js較為靈活的特點
xml在樹狀結構的表現上較為優秀
因為在嵌套層數較深、交互邏輯更複雜的情況下,xml+js比起js直接創建dom或CreateElement等方式來說更人性化、更易於維護
放止XSS DOM註入型攻擊
jsx會將標簽轉義為字元串,以防止惡意標簽被註入到頁面
// 頁面上展示文案: <a href="#">inner text<\/a>
const FC = ({value}) => <div>{value}</div>
ReactDOM.render(<FC value={`<a href="#">inner text<\/a>`} />, document.getElementById('app'))
// 頁面上出現a標簽,DOM被註入
const FC = ({value}) => <div dangerouslySetInnerHTML={{__html:value}}></div>
ReactDOM.render(<FC value={`<a href="#">inner text<\/a>`} />, document.getElementById('app'))
4.2 缺點
導致項目依賴增多
jsx必須依賴babel等編譯工具轉換成React.createElement才可以正常運行,導致項目依賴增多
5 深入react源碼解讀jsx到ReactElement
此後,jsx被編譯成了React.CreateElement,後面要做的事情就是執行這個方法並創建React元素。對後續細節感興趣可以看看這篇深入react源碼解讀jsx到ReactElement