JavaScript的React架構中的JSX文法學習入門教程_基礎知識

來源:互聯網
上載者:User

什麼是JSX?

在用React寫組件的時候,通常會用到JSX文法,粗看上去,像是在Javascript代碼裡直接寫起了XML標籤,實質上這隻是一個文法糖,每一個XML標籤都會被JSX轉換工具轉換成純Javascript代碼,當然你想直接使用純Javascript代碼寫也是可以的,只是利用JSX,組件的結構和組件之間的關係看上去更加清晰。

var MyComponent = React.createClass({/*...*/});var myElement = <MyComponent someProperty={true} />;React.render(myElement, document.body);

一個XML標籤,比如<MyComponent someProperty={true} />會被JSX轉換工具轉換成什麼呢?

比如:

var Nav = React.createClass({/*...*/});var app = <Nav color="blue"><Profile>click</Profile></Nav>;

會被轉化為:

var Nav = React.createClass({/*...*/});var app = React.createElement( Nav, {color:"blue"}, React.createElement(Profile, null, "click"));

那麼也就是說,我們寫一個XML標籤,實質上就是在調用React.createElement這個方法,並返回一個ReactElement對象。

ReactElement createElement( string/ReactClass type, [object props], [children ...])

這個方法的第一個參數可以是一個字串,表示是一個HTML標準內的元素,或者是一個ReactClass類型的對象,表示我們之前封裝好的自訂群組件。第二個參數是一個對象,或者說是字典也可以,它儲存了這個元素的所有固有屬性(即傳入後基本不會改變的值)。從第三個參數開始,之後的參數都被認作是元素的子項目。

JSX轉化器

要把帶有JSX文法的代碼轉化為純Javascript代碼,有多種方式,對於內聯與HTML中的代碼或者是未經過轉化的外部檔案,在script標籤中要加上type="text/jsx",並引入JSXTransformer.js檔案即可,不過這種方式並不建議在生產環境使用,建議的方法是在代碼上線前就將代碼轉換好,可以使用npm全域安裝react-tools:

npm install -g react-tools

並使用命令列工具轉化即可(具體用法可以參考jsx -h):

jsx src/ build/

如果使用自動化工具,比如gulp的話,可以使用相應外掛程式gulp-react。

HTML模板中使用JS

在HTML模板中使用JS非常方便,只需要用大括弧把JS代碼括起來即可。

var names = ['Alice', 'Emily', 'Kate'];  React.render( <div> { names.map(function (name) { return <div>Hello, {name}!</div> }) } </div>, document.getElementById('example') ); 

編譯出來就變成了這樣:

var names = ['Alice', 'Emily', 'Kate']; React.render(  React.createElement("div", null, names.map(function (name) {  return React.createElement("div", null, "Hello, ", name, "!")  }) ),  document.getElementById('example') ); 

要注意的是,大括弧實際就是一個變數輸出運算式,JSX最終就是直接把花括弧中的內容作為 React.createElement 的第三個參數直接傳入了(沒有任何修改直接傳入),所以其中只能放一行運算式,並且任何不能直接作為第三個參數的寫法都是錯的,那麼你這樣寫就是錯的:

React.render( <div> { var a = 1; names.map(function (name) { return <div>Hello, {name}!</div> }) } </div>, document.getElementById('example') ); 

因為很明顯其中花括弧內的內容直接放在第三個參數上,文法不對。

這麼寫也是錯的:

React.render( <div> { var a = 1;  } </div>, document.getElementById('example') ); 

因為 React.createElement(“div”, null, var a = 1;) 是語法錯誤。
那麼你也可以理解為什麼大括弧中的js運算式不能有分號結尾了吧。

需要注意的是,如果你在屬性中輸出JS變數,是不能加引號的,不然會被當做字串而不被解析。
應該是這樣:

<a title={title}>連結</a>

使用HTML標籤

要建立一個HTML標準中存在的元素,直接像寫HTML代碼一樣即可:

var myDivElement = <div className="foo" />;React.render(myDivElement, document.body);

不過需要注意的是class和for這兩個屬性,JSX文法最終是要被轉換為純Javascript的,所以要和在Javascript DOM中一樣,用className和htmlFor。

還有一點是,在建立HTML標準內的元素時,JSX轉化器會丟棄那些非標準的屬性,如果一定要添加自訂屬性,那麼需要在這些自訂屬性之前添加data-首碼。

<div data-custom-attribute="foo" />

命名空間式組件

比如開發組件的時候,一個組件有多個子組件,你希望這些子組件可以作為其父組件的屬性,那麼可以像這樣用:

var Form = MyFormComponent;var App = ( <Form> <Form.Row>  <Form.Label />  <Form.Input /> </Form.Row> </Form>);

這樣你只需將子組件的ReactClass作為其父組件的屬性:

var MyFormComponent = React.createClass({ ... });MyFormComponent.Row = React.createClass({ ... });MyFormComponent.Label = React.createClass({ ... });MyFormComponent.Input = React.createClass({ ... });

而建立子項目可以直接交給JSX轉化器:

var App = ( React.createElement(Form, null,  React.createElement(Form.Row, null,   React.createElement(Form.Label, null),   React.createElement(Form.Input, null)  ) ));

該功能需要0.11及以上版本

Javascript運算式

在JSX文法中寫Javascript運算式只需要用{}即可,比如下面這個使用三目運算子的例子:

// Input (JSX):var content = <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>;// Output (JS):var content = React.createElement( Container, null, window.isLoggedIn ? React.createElement(Nav) : React.createElement(Login));

不過要注意的是,JSX文法只是文法糖,它的背後是調用ReactElement的構造方法React.createElement的,所以類似這樣的寫法是不可以的:

// This JSX:<div id={if (condition) { 'msg' }}>Hello World!</div>// Is transformed to this JS:React.createElement("div", {id: if (condition) { 'msg' }}, "Hello World!");

可以從轉化後的Javascript代碼中看出明顯的語法錯誤,所以要不用三目運算子,要不就這樣寫:

if (condition) <div id='msg'>Hello World!</div>else <div>Hello World!</div>

傳播屬性(Spread Attributes)

在JSX中,可以使用...運算子,表示將一個對象的索引值對與ReactElement的props屬性合并,這個...運算子的實作類別似於ES6 Array中的...運算子的特性。

var props = { foo: x, bar: y };var component = <Component { ...props } />;

這樣就相當於:

var component = <Component foo={x} bar={y} />

它也可以和普通的XML屬性混合使用,需要同名屬性,後者將覆蓋前者:

var props = { foo: 'default' };var component = <Component {...props} foo={'override'} />;console.log(component.props.foo); // 'override'

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.