React入門筆記(一) — 深入理解JSX

來源:互聯網
上載者:User
《一》、理解JSX

  JSXJavascrpt XML— — 一種在React組件內部構建標籤的類XML文法。
  JSX並不是新語言,也沒有改變JavaScript的文法,只是一種基於ECMAScript的新特性,一種定義帶屬性樹結構(DOM結構)的文法
  React 可以不使用 JSX 來編寫組件,但是使用 JSX 可以讓代碼可讀性更高、語義更清晰、對 React 元素進行抽象等等。 一、使用JSX好處

  1、允許使用熟悉的文法來定義HTML元素樹  2、提供了更加語義化且易懂的標籤
  3、程式結構更容易被直觀化  4、抽象了React Element的建立過程
  5、可以隨時掌控HTML標籤以及產生這些標籤的代碼  63、是原生Javascript

使用JSX和不使用JSX的代碼對比如下:

//開閉標籤,在構建複雜的樹形結構時,比函數調用和對象字面量更易讀//#使用JSX<div className="red">Children Text</div>;<MyCounter count={3 + 5} />;// 此處給一個js對象設定"scores"屬性var gameScores = {  player1: 2,  player2: 5};<DashboardUnit data-index="2">  <h1>Scores</h1>  <Scoreboard className="results" scores={gameScores} /></DashboardUnit>;//#不使用JSXReact.createElement("div", { className: "red" }, "Children Text");React.createElement(MyCounter, { count: 3 + 5 });React.createElement(  DashboardUnit,  { "data-index": "2" },  React.createElement("h1", null, "Scores"),  React.createElement(Scoreboard, { className: "results", scores: gameScores }));
二、JSX 文法

【注意】 JSX代碼需經babel 編譯成javscript,目前主流瀏覽器才能正常識別,即在head中需添加:

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>

React還需依賴的另外2個檔案:react.js 是 React 的核心庫,react-dom.js 是提供與 DOM 相關的功能,
並將JSX代碼放在<script type='text/babel'> … </script>中編寫

<!DOCTYPE html><html>  <head>    <meta charset="UTF-8" />    <title>Hello React!</title>    <script src="build/react.js"></script>    <script src="build/react-dom.js"></script>    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>  </head>  <body>    <div id="example"></div>    <script type="text/babel">      ReactDOM.render(        <h1>Hello, world!</h1>,        document.getElementById('example')      );    </script>  </body></html>

【推廣】上面必需核心庫找不到的話,可以上本人github下載:https://github.com/mqy1023/react-basejs

  JSX是HTML和JavaScript混寫的文法,當遇到<JSX就當HTML解析,遇到 { 就當JavaScript解析。

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


理解Array.prototype.map,返回一個新的數組

var friends = ['Jake Lingwall', 'Murphy Randall', 'Merrick Christensen'];var listItems = friends.map(function(friend){  return "<li> " + friend + "</li>";});console.log(listItems); // ["<li> Jake Lingwall</li>", "<li> Murphy Randall</li>", "<li> Merrick Christensen</li>"];

  JSX 允許直接在模板插入 JavaScript 變數。如果這個變數是一個數組,則會展開這個數組的所有成員

// arr變數是一個數組,結果 JSX 會把它的所有成員,添加到模板var arr = [  <h1>Hello world!</h1>,  <h2>React is awesome</h2>,];ReactDOM.render(  <div>{arr}</div>,  document.getElementById('example'));

  在React中,一個組件的HTML標籤與產生這些標籤的代碼內在地緊密聯絡在一起。這意味和我們可以輕鬆地利用Javascript強大魔力
  1、使用三目運算子

render: function() {   return <div className={this.state.isComplete ? 'is-complete' : ''}>...</div>;}

  2、使用變數/函數

getIsComplete: function() {   return this.state.isComplete ? 'is-complete' : '';},render: function() {   var isComplete = this.getIsComplete();   return <div className={isComplete}>...</div>;   //或者直接返回函數   return <div className={this.getIsComplete()}>...</div>;}

  3、使用邏輯與(&&)或者邏輯或( || )運算子
    由於對於null或false值React不會輸出任何內容,因此可以使用一個後面跟隨了期望字串的布爾值來實現條件判斷。如果這個布爾值為true,後續字串會被使用

render: function() {   return <div className={this.state.isComplete && 'is-complete'}>...</div>;}

    邏輯或,this.props.name為空白時,className值等於is-complete

render: function() {   return <div className={this.props.name || 'is-complete'}>...</div>;}

  4、函數調用

var HelloWorld = React.createClass({    render: function () {        return <p>Hello, {(function (obj) {             return obj.props.name ? obj.props.name : "World";        })(this)}</p>    }});
三、建立並渲染組件
//1、React.createClass 是用來建立一個組件var HelloMessage = React.createClass({  render: function() {    return <h1>Hello {this.props.name}</h1>;  }});//2、ReactDOM.render渲染組件ReactDOM.render(  <HelloMessage name="John" />,  document.getElementById('example'));
《二》、JSX和HTML不同點
一、渲染HTML標籤和React組件

  React.render方法可以渲染HTML結構,也可以渲染React組件。
    1、渲染HTML標籤,聲明變數採用首字母小寫

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

    2、渲染React組件,聲明變數採用首字母大寫

var MyComponent = React.createClass({/*...*/});var myElement = <MyComponent someProperty={true} />;ReactDOM.render(myElement, document.body);
二、非DOM屬性

1、鍵(key)
  key是一個可選的唯一識別碼,當兩個已經在於DOM中的組件交換位置時,React能夠匹配對應的key並進行相應的移動,且不需要完全重新渲染DOM,提供渲染效能

2、引用(ref)
  ref允許父組件在render方法之外保持對子組件的一個引用。在JSX中,你可以通過屬性中設定期望的引用名來定義一個引用。

render: function() {   return <div>             <input ref="myInput" ...> </input>          </div>    );}

  然後你可以在組件的任何地方使用this.refs.myInput擷取這個引用了。通過引用擷取到的這個對象被稱為支援執行個體。它並不是真的DOM,而是React在需要時用來建立DOM的一個描述對象。你可以使用this.refs.myInput.getDOMNode()訪問真實的DOM節點。

3、設定原始的HTML
  比如我們有一些內容是使用者輸入的富文本,希望展示相應的樣式

var content='<strong>content</strong>';ReactDOM.render(    <div>{content}</div>,    document.body);

結果頁面直接輸出內容了:

React預設會進行HTML的轉義,避免XSS攻擊,如果要不轉義,可以這麼寫:

ReactDOM.render(    <div dangerouslySetInnerHTML={{__html: "<strong>content</strong>"}}></div>,    document.body);
三、事件

  在所有的瀏覽器中,事件名已經被正常化並統一用onXXX駝峰形式表示

var BannerAd = React.createClass({    handleClick: function(event) {        //...    },    render: function() {       return <div onClick={this.handleClick}>Click Me!</div>;    }})

【注意】 React自動綁定了組件所有方法的範圍,因此你不需要手動綁定

handleClick: function(event) {...},render: function() {   //反模式 ————在React中手動給組件執行個體綁定   //函數範圍是沒有必要的   return <div onClick={this.handleClick.bind(this)}>...</div>;}
四、特殊屬性

  由於JSX會轉換為原生的Javascript函數,因此有一些關鍵詞我們是不能用的——如classfor,對應JSX中屬性寫成classNamehtmlFor

//#使用JSXReactDOM.render(    <label className="xxx" htmlFor="input">content</label>,    document.getElementById('example'));//#不使用JSXReactDOM.render(    React.createElement('label', {className: 'xxx', htmlFor: 'input'}, 'content'),    document.getElementById('example'));
五、style樣式

  React把所有的內聯樣式都正常化為駝峰形式,與Javascript中DOM的sytle屬性一致。第一重大括弧表示這是 JavaScript 文法,第二重大括弧表示樣式對象。

React.render(    <div style={{color:'red'}}>        xxxxx    </div>,    document.body);////////////////////////////var style = {    color:'red',    borderColor: '#999'}ReactDOM.render(<div style={style}>xxxxx</div>, document.body);
六、注釋

JSX本質就是Javascript,因此你可以在標籤內添加原生的javascript注釋。 注釋兩種形式
當作一個元素的子節點 內聯在元素的屬性中

var content = (  <Nav>    {/* 一般注釋, 用 {} 包圍 */}    <Person      /* 多         行         注釋 */      name={window.isLoggedIn ? window.name : ''} // 行章節附註釋    />  </Nav>);
《三》、JSX延伸屬性
一、不要改變props

  如果提前就知道了組件的屬性的話,寫起來很容易。例如component組件有兩個動態屬性foo和bar:

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

  而實際上,有些屬性可能是後續添加的,我們沒辦法一開始就確定,我們可能會寫出下面不好的代碼:

var component = <Component />;component.props.foo = x; // badcomponent.props.bar = y; // also bad

  這樣寫是錯誤的,因為我們手動直接添加的屬性React後續沒辦法檢查到屬性類型錯誤,也就是說,當我們手動添加的屬性發生類型錯誤時,在控制台是看不到錯誤資訊的。

  在React的設定中,初始化完props後,props是不可變的。改變props會引起無法想象的後果。 二、延伸屬性

  為瞭解決這個問題,React引入了屬性延伸

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

  當需要拓展我們的屬性的時候,定義個一個屬性對象,並通過{...props}的方式引入,React會幫我們拷貝到組件的props屬性中。重要的是—這個過程是由React操控的,不是手動添賦值的屬性。

  需要覆蓋的時候可以這樣寫:

var props = { foo: 'default' };var component = <Component {...props} foo={'override'} />;console.log(component.props.foo); // 'override'
《四》、JSX 陷阱
一、自訂HTML 屬性

  如果往原生 HTML 元素裡傳入 HTML 規範裡不存在的屬性,React 不會顯示它們。

ReactDOM.render(    <div dd='xxx'>content</div>,    document.body);

如果需要使用自訂屬性,要加 data- 首碼。

ReactDOM.render(    <div data-dd='xxx' aria-dd='xxx'>content</div>,    document.body);

二、組件render渲染函數中return注意點
如果return和JSX語句開頭在同一行時,不需要括弧;否則要括弧包裹

//正確寫法1var HelloMessage = React.createClass({  render: function() {    return <h1>        Hello {this.props.name}</h1>;  }});//正確寫法2render: function() {    return <h1>Hello {this.props.name}</h1>;}//正確寫法3render: function() {    return (        <h1>Hello {this.props.name}</h1>);}//錯誤寫法render: function() {    return         <h1>Hello {this.props.name}</h1>;}



參考連結
1、《React學習筆記—JSX》https://segmentfault.com/a/1190000002646155
2、《React引領未來的使用者介面開發架構》
3、http://facebook.github.io/react/docs/jsx-in-depth.html
4、http://www.jikexueyuan.com/course/969_3.html?ss=1
5、http://buildwithreact.com/tutorial/jsx

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.