首先,嚴格定義上來講,JSX 是 react 提供的一種標籤式的組件聲明語法。JSX 只是一種js語言的擴展語法糖,在正式環境運行前,須要通過 babel 工具編譯爲正式的 JS 代碼。javascript
在正式介紹JSX 以前,咱們有必要理解,react 框架實現了 virtual dom 功能,開發者可經過react的雙向綁定、組件、組件嵌套等工具,將頁面的構建邏輯交付於react框架便可,而無需執行實際的 DOM 操做。爲了實現 virtual dom ,react 將 DOM 映射爲 Component 對象,將 DOM 樹映射爲組件樹。爲此,react提供了 createClass
接口用於定於 Component;提供了 createElement
接口用於構建組件樹。html
JSX 高度兼容HTML,即便是react新手也能夠迅速寫出 JSX 代碼:vue
const element = <div> <button>這是一個 button</button> <button style={{ width: 100 }}>這是一個包含 style 屬性的 button</button> <button className="btn btn-default">這是一個帶 className 的 button</button> <button className="btn btn-default" onClick={() => alert('click me')}>這是一個帶事件處理的 button</button> <div className="btn-group"> <button className="btn btn-default">這是被 div 包圍的 button</button> <button className="btn btn-default">這也是被 div 包圍的 button</button> </div> </div>;
這是JSX的基本形式,編譯後的代碼:java
var element = _react2.default.createElement( 'div', null, _react2.default.createElement( 'button', null, '\u8FD9\u662F\u4E00\u4E2A button' ), _react2.default.createElement( 'button', { style: { width: 100 } }, '\u8FD9\u662F\u4E00\u4E2A\u5305\u542B style \u5C5E\u6027\u7684 button' ), _react2.default.createElement( 'button', { className: 'btn btn-default' }, '\u8FD9\u662F\u4E00\u4E2A\u5E26 className \u7684 button' ), _react2.default.createElement( 'button', { className: 'btn btn-default', onClick: function onClick() { return alert('click me'); } }, '\u8FD9\u662F\u4E00\u4E2A\u5E26\u4E8B\u4EF6\u5904\u7406\u7684 button' ), _react2.default.createElement( 'div', { className: 'btn-group' }, _react2.default.createElement( 'button', { className: 'btn btn-default' }, '\u8FD9\u662F\u88AB div \u5305\u56F4\u7684 button' ), _react2.default.createElement( 'button', { className: 'btn btn-default' }, '\u8FD9\u4E5F\u662F\u88AB div \u5305\u56F4\u7684 button' ) ) );
與html主要的不一樣點爲:react
不能使用 class
聲明元素類,改用 className
web
綁定事件必須使用 駝峯命名babel
style 屬性必須爲對象框架
JSX中,父組件可經過屬性方式,將配置值傳遞到子組件中:dom
const element = <div tabIndex="0" name="someDiv"></div>;
標籤屬性最終被編譯成對象,傳遞到 createElement
接口,如上述代碼編譯結果爲:ide
var element = React.createElement("div", { tabIndex: "0", name: "someDiv" });
屬性值既接受字符串,也接受js表達式,一樣經過 {}
閉合,如:
const areWeRocking = true; const element = <div areWeRocking={areWeRocking}></div>;
JSX 中,標籤能夠包含子標籤,子標籤集合會被編譯爲 children
傳遞到 createElement
函數,如:
const element = <div> <button>這是一個button</button> </div>;
編譯結果:
var element = React.createElement( "div", null, React.createElement( "button", null "\u8FD9\u662F\u4E00\u4E2Abutton" ) );
JSX 支持嵌套 js表達式,方式很是簡單,使用 {}
包含表達式便可,這使得咱們能夠輕易地在JSX實現各類邏輯
循環
const array = [1, 2, 3, 4]; const element = <div>{array.map(item => <span>{item}</span>)}</div>;
分支
const areWeRocking = true; const element = <div>{areWeRocking ? 'awesome' : 'holy shit'}</div>;
函數
const giveMeYourName = () => <strong>tecfan</strong>; const element = <div>{giveMeYourName()}</div>;
JSX 表達能力很是強,一是能夠無限制的嵌套組件標籤、js代碼,實現複雜邏輯;二是支持函數表達式,經過函數咱們能夠實現任意功能。
JSX 語法並不晦澀,只有三條簡簡單單的規則:
經過 XML 形式聲明
標籤容許聲明任意屬性
標籤內能夠嵌套子標籤,也能夠嵌套js表達式
編譯器而言的處理邏輯也會變的很簡單:
解析標籤名(tagName)
解析標籤屬性,拼合爲屬性對象(props)
遍歷內容集合(children)
若是內容爲JS表達式,執行表達式,並將結果存入 children 變量
若是內容爲標籤,執行第一步,並將結果存入 children 變量
上面過程當中生成的變量 tagNaem、props、children 被傳遞到 createElement
接口:
React.createElement( tagName, props, ...children )
在web領域咱們見過太多模板,angular、vue、lodash、swig...各類模板都構造了其獨特的語法、控制結構,許多甚至已經大幅度偏離html語法基礎。
JSX 則成功的另闢小徑,只提供基於html的語法糖,只要熟悉html、js,入門難度很是低。良好的程序結構,應該是簡單純粹,而又不失表達能力的,JSX正符合這種良好設計。