書籍完整目錄javascript
官方文檔 https://facebook.github.io/react/docs/jsx-in-depth.htmlhtml
JSX 語法聽上去很討厭,但當真正使用的時候會發現,JSX 的寫法在組件的組合和屬性的傳遞上提供了很是靈活的解決方案。 java
在學習本節的時候,但願讀者在閱讀的同時可以實際編碼體驗 JSX ,寫代碼的意思是真的要寫.代.碼。react
爲了快速開始 JSX 的學習,咱們能夠經過以下幾種方式快速進入 React 開發環境git
Babel REPLgithub
直接在 REPL 中寫 JSX 語法,能夠實時的查看編譯後的結果。ajax
在線模式 React Fiddlesegmentfault
第一步:打開編輯器,新建一個 hello-react.html
文件
第二步:粘貼 Hello, world 代碼數組
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Hello React!</title> <script src="http://facebook.github.io/react/js/react.js"></script> <script src="http://facebook.github.io/react/js/react-dom.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script> </head> <body> <div id="example"></div> <script type="text/babel"> var Hello = React.createClass({ render: function render() { return <div>Hello {this.props.name}</div>; } }); ReactDOM.render( <Hello name="World" />, document.getElementById('example') ); </script> </body> </html>
https://github.com/leanklass/leanreact/tree/hello-worldbabel
建立 JSX 語法的本質目的是爲了使用基於 xml 的方式表達組件的嵌套,保持和 HTML 一致的結構,語法上除了在描述組件上比較特別之外,其它和普通的 Javascript 沒有區別。 而且最終全部的 JSX 都會編譯爲原生 Javascript。
須要提醒讀者的是,React 的不少例子都是經過 ES6 來寫的, 但這並非 JSX 語法,後面咱們會有單獨的一小節講解 ES6 的基本語法,不過目前爲止咱們先將跟多精力放在 JSX 上。
JSX 構建組件的規則和 xml 規則一致
標籤能夠任意的嵌套
eg:
function render() { return <p> text content <ul> <li>....</li> <li>....</li> </ul> </p> }
標籤必須嚴格閉合,不然沒法編譯經過
自閉合:
function render() { return <input type="text"/> }
標籤閉合:
function render() { return <p>....</p> }
JSX 組件分爲 HTML 組件和 React 組件
HTML 組件就是 HTML 中的原生標籤, 如:
function render() { return <p> hello, React World </p> } function render() { return <ul> <li>list item 1</li> <li>list item 2</li> </ul> }
React 組件就是自定義的組件,如
// 定義一個自定義組件 var CustomComponnet = React.createClass({ render: function() { return <div> custom component </div> } }); // 使用自定義組件 function render() { return <p> <CustomComponent/> </p> }
和 html 同樣,JSX 中組件也有屬性,傳遞屬性的方式也相同
對於 HTML 組件
function render() { return <p title="title" >hello, React, world </p> }
若是是 React 組件能夠定義自定義屬性,傳遞自定義屬性的方式:
function render() { return <p> <CustomComponent customProps="data"/> </p> } }
屬性便可以是字符串,也能夠是任意的 Javascript 變量
, 傳遞方式是將變量用花括號, eg:
function render() { var data = {a: 1, b:2}; return <p> <CustomComponent customProps={data}/> </p> }
須要注意的地方上,屬性的寫法上和 HTML 存在區別,在寫 JSX 的時候,全部的屬性都是駝峯式的寫法,如:
function render() { return <div className="..."> <label htmlFor="..."></label> <input onChange="..."/> </div> }
而原生的寫法爲:
<div class="..."> <label for="..."></label> <input onchange="..."/> </div>
主要是出於標準的緣由,駝峯式是 Javascript 的標準寫法,而且 React 底層是將屬性直接對應到原生 DOM 的屬性,而原生 DOM 的屬性是駝峯式的寫法,這裏也能夠理解爲何類名不是 class 而是 className 了, 又由於 class 和 for 仍是 js 關鍵字,因此 jsx 中:
class => className
for => htmlFor
除此以外比較特殊的地方是 data-*
和 aria-*
兩類屬性是和 HTML 一致的。
不少狀況,咱們須要將 JS 中的文本直接顯示,作法和顯示變量屬性同樣,用花括號
function render() { var text = "Hello, World" return <p> {text} </p> }
花括號裏邊實際上除了變量之外,能夠是一段 JS 表達式,咱們能夠利用花括號作簡單的運算:
funtion render() { var text = text; var isTrue = false; var arr = [1, 2, 3]; return <p> {text} {isTrue ? "true" : "false"} {arr.map(function(it) { return <span> {it} </span> })} </p> }
註釋的寫法以下:
function render() { return <p> /* 這裏是註釋內容 */ </p> }
render 方法返回的組件必須是有且只有一個根組件,錯誤狀況的例子
// 沒法編譯經過,JSX 會提示編譯錯誤 function render() { return (<p> .... </p> <p> .... </p>) }
JSX 能夠經過命名空間的方式使用組件, 經過命名空間的方式能夠解決相同名稱不一樣用途組件衝突的問題。
如:
function render() { return <p> <CustomComponent1.SubElement/> <CustomComponent2.SubElement/> </p> }
JSX 的寫法最終會被編譯成原生的 Javascript。 若是你願意的話,也能夠直接寫編譯後的 JS, 不過最好是寫 JSX, 由於 JSX 的目的就是爲了簡化寫法,並保持和 HTML 相同的開發體驗。
JSX 具體的編譯方式有兩種
在 HTML 中引入 babel 編譯器, 如上 Hello World 程序中同樣。
離線編譯 JSX,經過 babel 編譯 JSX,細節咱們將在第二章中講解。
Hello World 程序轉化爲 JS 的代碼以下:
var Hello = React.createClass({ displayName: 'Hello', render: function() { return React.createElement("div", null, "Hello ", this.props.name); } }); ReactDOM.render( React.createElement(Hello, {name: "World"}), document.getElementById('container') );
能夠看出:
<Hello .../> <=> React.createElement(Hello, ....)
xml 的寫法其實是調用 React 的工廠方法 createElement。
當理解了 JSX 最終會編譯爲 JS 就能夠理解 JSX 的一些特性如命名空間,組件實際上就是一個 Javascript 對象,命名空間下的組件至關於對象的屬性
TODOMVC 以代辦事項列表爲需求模型,包含了各類框架的實現。 本例子的目的爲了讓讀者可以切身的體會 JSX 的使用方法。
根據一個 JSON 對象,用 React JSX 的方式渲染出 TODOMVC 頁面:
JSON 對象以下:
var todolist = { name: "todos", todos: [{ completed: false, title: 'finish exercise' }, { completed: false, title: 'lean jsx' }, { completed: true, title: 'lean react' }] }
修改 hello world index.html 中的代碼,爲了簡化問題, 咱們能夠直接複製 TODOMVC 中的 HTML 和 CSS 。
class 要寫爲 className
input 標籤未閉合
數組遍歷事後要添加 key 屬性,不然會提示 error 信息(在組件章節會講解)
html 轉 JSX工具, Facebook 提供了 html 轉 JSX 組件的工具,能夠直接複製 html 轉爲 JSX 組件