JavaScript的React框架中的JSX語法學習入門教程

字號:


    這篇文章主要介紹了JavaScript的React框架中的JSX語法學習入門教程,React是由Facebook開發(fā)并開源的高人氣js框架,需要的朋友可以參考下
    什么是JSX?
    在用React寫組件的時候,通常會用到JSX語法,粗看上去,像是在Javascript代碼里直接寫起了XML標簽,實質(zhì)上這只是一個語法糖,每一個XML標簽都會被JSX轉(zhuǎn)換工具轉(zhuǎn)換成純Javascript代碼,當然你想直接使用純Javascript代碼寫也是可以的,只是利用JSX,組件的結(jié)構(gòu)和組件之間的關(guān)系看上去更加清晰。
    var MyComponent = React.createClass({/*...*/});
    var myElement = <MyComponent someProperty={true} />;
    React.render(myElement, document.body);
    一個XML標簽,比如<MyComponent someProperty={true} />會被JSX轉(zhuǎn)換工具轉(zhuǎn)換成什么呢?
    比如:
    var Nav = React.createClass({/*...*/});
    var app = <Nav color="blue"><Profile>click</Profile></Nav>;
    會被轉(zhuǎn)化為:
    var Nav = React.createClass({/*...*/});
    var app = React.createElement(
     Nav,
     {color:"blue"},
     React.createElement(Profile, null, "click")
    );
    那么也就是說,我們寫一個XML標簽,實質(zhì)上就是在調(diào)用React.createElement這個方法,并返回一個ReactElement對象。
    ReactElement createElement(
     string/ReactClass type,
     [object props],
     [children ...]
    )
    這個方法的第一個參數(shù)可以是一個字符串,表示是一個HTML標準內(nèi)的元素,或者是一個ReactClass類型的對象,表示我們之前封裝好的自定義組件。第二個參數(shù)是一個對象,或者說是字典也可以,它保存了這個元素的所有固有屬性(即傳入后基本不會改變的值)。從第三個參數(shù)開始,之后的參數(shù)都被認作是元素的子元素。
    JSX轉(zhuǎn)化器
    要把帶有JSX語法的代碼轉(zhuǎn)化為純Javascript代碼,有多種方式,對于內(nèi)聯(lián)與HTML中的代碼或者是未經(jīng)過轉(zhuǎn)化的外部文件,在script標簽中要加上type="text/jsx",并引入JSXTransformer.js文件即可,不過這種方式并不建議在生產(chǎn)環(huán)境使用,建議的方法是在代碼上線前就將代碼轉(zhuǎn)換好,可以使用npm全局安裝react-tools:
    npm install -g react-tools
    并使用命令行工具轉(zhuǎn)化即可(具體用法可以參考jsx -h):
    jsx src/ build/
    如果使用自動化工具,比如gulp的話,可以使用相應(yīng)插件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最終就是直接把花括號中的內(nèi)容作為 React.createElement 的第三個參數(shù)直接傳入了(沒有任何修改直接傳入),所以其中只能放一行表達式,并且任何不能直接作為第三個參數(shù)的寫法都是錯的,那么你這樣寫就是錯的:
    React.render( 
    <div> 
    { 
    var a = 1; 
    names.map(function (name) { 
    return <div>Hello, {name}!</div> 
    }) 
    } 
    </div>, 
    document.getElementById('example') 
    ); 
    因為很明顯其中花括號內(nèi)的內(nèi)容直接放在第三個參數(shù)上,語法不對。
    這么寫也是錯的:
    React.render( 
    <div> 
    { 
    var a = 1; 
    } 
    </div>, 
    document.getElementById('example') 
    ); 
    因為 React.createElement(“div”, null, var a = 1;) 是語法錯誤。
    那么你也可以理解為什么大括號中的js表達式不能有分號結(jié)尾了吧。
    需要注意的是,如果你在屬性中輸出JS變量,是不能加引號的,不然會被當做字符串而不被解析。
    應(yīng)該是這樣:
    <a title={title}>鏈接</a>
    使用HTML標簽
    要創(chuàng)建一個HTML標準中存在的元素,直接像寫HTML代碼一樣即可:
    var myDivElement = <div className="foo" />;
    React.render(myDivElement, document.body);
    不過需要注意的是class和for這兩個屬性,JSX語法最終是要被轉(zhuǎn)換為純Javascript的,所以要和在Javascript DOM中一樣,用className和htmlFor。
    還有一點是,在創(chuàng)建HTML標準內(nèi)的元素時,JSX轉(zhuǎn)化器會丟棄那些非標準的屬性,如果一定要添加自定義屬性,那么需要在這些自定義屬性之前添加data-前綴。
    <div data-custom-attribute="foo" />
    命名空間式組件
    比如開發(fā)組件的時候,一個組件有多個子組件,你希望這些子組件可以作為其父組件的屬性,那么可以像這樣用:
    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({ ... });
    而創(chuàng)建子元素可以直接交給JSX轉(zhuǎn)化器:
    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語法只是語法糖,它的背后是調(diào)用ReactElement的構(gòu)造方法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!");
    可以從轉(zhuǎn)化后的Javascript代碼中看出明顯的語法錯誤,所以要不用三目運算符,要不就這樣寫:
    if (condition) <div id='msg'>Hello World!</div>
    else <div>Hello World!</div>
    傳播屬性(Spread Attributes)
    在JSX中,可以使用...運算符,表示將一個對象的鍵值對與ReactElement的props屬性合并,這個...運算符的實現(xiàn)類似于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'