React.js入門學習第一篇_javascript技巧

來源:互聯網
上載者:User

一、JSX介紹

①定義

JSX=JavaScript XML,是一種在React組件內部構建標籤的類XML文法。React在不使用JSX的情況下一樣可以工作,但是使用JSX可以提高組件的可讀性,增強JS語義,結構清晰,抽象程度高,代碼模組化。因此推薦在React中使用JSX。

②特點

1、元素名首字母大寫

2、符合嵌套規則

3、可以寫入求值運算式

4、駝峰式命名

5、不能使用javascript原生函數的一些關鍵詞,如for和class。需要替換成htmlFor和className

③使用方法

1、使用動態值:JSX將兩個花括弧之間的內容{...}渲染為動態值,花括弧指明了一個javascript上下文環境,花括弧裡面可以是一個變數,也可以是函數。 例如:

var name=“winty”;<p>{name}</p>function date(d){ return [ d.getFullYear(), d.getMonth()+1, d.getDate() ].join('-);};<p>{date(new Date()}</p>

2.注釋:首先,在子節點中注釋要用大括弧包裹起來,然後就可以單行注釋/**/,也可以多行注釋//。

var Hello=React.createClass({  render:function(){   return <p name="winty"> //set name     Hello ,World     /*     多行注釋     多行注釋     */     </p>   } });

3.使用CSS內聯樣式

var style={ color:#000;};React.render(<div style={style}>....</div>,document.body);

4.使用條件判斷

//方法1,三目運算子var Hello=React.createClass({  render:function(){  return <p>Hello,{this.props.name?this.props.name : "LuckyWinty"}</p>  }});//方法2,if-else語句var Hello1=React.createClass({  getName:function(){   if(this.props.name)   return this.props.name;   else   return "LuckyWinty";  render:function(){  return <p>Hello,{this.getName}</p>  }});//方法3,使用邏輯||運算子var Hello3=React.createClass({  render:function(){  return <p>Hello,{this.props.name||"LuckyWinty"}</p>  }});

④非DOM屬性介紹

JSX中有3個非DOM屬性,分別是:dangerouslySetInnerHTML、ref、key。

dangerouslySetInnerHTML:在JSX中直接插入HTML代碼,但是如果能避免使用這個屬性則盡量避免使用。

不合時宜的使用 innerHTML 可能會導致 cross-site scripting (XSS) 攻擊。 淨化使用者的輸入來顯示的時候,經常會出現錯誤,不合適的淨化也是導致網頁攻擊 的原因之一。
在徹底的理解安全問題後果並正確地淨化資料之後,產生只包含唯一 key __html 的對象,並且對象的值是淨化後的資料。例如:

function createMarkup() {  return {__html: 'First · Second'}; };<div dangerouslySetInnerHTML={createMarkup()} />

ref:父組件引用子組件,你可以通過在屬性中設定期望的引用名來定義一個引用。例如:

...render:function(){ return <div>   <input ref="MyInput" .../>   </div>}...//然後你就可以在組件中的任何地方使用this.refs.myInput擷取這個引用了

key:是一個可選的唯一識別碼,通過給組件設定一個獨一無二的鍵,並確保它在一個渲染周期中保持一致,使得React能夠更只能地決定應該重用一個組件還是銷毀並重建一個組件,進而提高渲染效能。例如:

var Hello3=React.createClass({  render:function(){  return <ul>    <li key="1">1</li>    <li key="2">2</li>    <li key="3">3</li>   </ul>  }});

二、React組件生命週期詳解

組件本質上就是狀態機器,輸入確定,輸出一定確定。狀態和結果一一對應,從而使程式變得直觀。狀態發生轉換時會觸發不同的鉤子函數,從而讓開發人員有機會做出響應。可以用事件的思路來理解狀態,但是事件與事件之間互相獨立,但是不同狀態之間可能會互相影響。
組件的所有狀態結合起來就成了組件的生命週期。即:初始化階段->運行中階段->銷毀階段。 

不同生命週期內可以自訂的函數
初始化階段:
①getDefaultProps:擷取預設屬性,只調用一次,是在createClass之後調用的。執行個體之間共用引用
②getInitialState:初始化每個執行個體的特有初始化狀態
③componentWillMount:mout就是裝載的意思,這個方法的意思就是說組件即將被裝載到頁面中,也是render之前最後一次修改狀態的機會
④render:組件在render函數產生虛擬節點,最後由react將虛擬節點變成真正的節點渲染到頁面上。只能訪問this.props和this.state,只有一個頂層組件,最好不要修改狀態和DOM輸出。
⑤componentDidMount:組件被裝載後才會被調用,也就是說調用這個方法的時候,組件已經被渲染到了頁面上,這個時候可以修改DOM
這五個函數的執行順序就是從上到下的。需要注意的是getDefaultProps只會在組件的第一個執行個體被初始化的時候被調用,也就是說第二個執行個體之後都是從getInitialState開始調用。同一個組件的所有執行個體的預設屬性都是一樣的。
主要測試代碼:

<script type="text/babel"> var Hello=React.createClass({  getDefaultProps:function(){   console.log("getDefaultProps, 1");  },  getInitialState:function(){   console.log("getInitialState, 2");   return null;  },  componentWillMount:function(){   console.log("componentWillMount, 3");  },  render:function(){   console.log("render, 4");   return <p>Hi,LuckyWinty!</p>  },  componentDidMount:function(){   console.log("componentDidMount, 5");  }, }); React.render(<Hello></Hello>,document.body);</script>

運行結果:

運行中階段:

①componentWillReceiveProps:這個函數在組件即將接收到屬性時觸發的,或者是父組件的屬性發生變化時,屬性在傳送到組件之前,開發人員有機會通過這個函數去處理屬性。比如修改,更新內部狀態等。
②shouldComponentUpdate:當組件接收到新屬性或者新狀態的時候觸發的。這個是一個疑問函數,也就是說我們可以告訴react不去更新某個組件。因為有時候屬性或者狀態並不會導致組件發生更新。在組件不需要更新的情況下,手動使shouldComponentUpdate返回false,這樣react就不需要再經過render和diff演算法去判斷是否要更新,從而提高效能。
③componentWillUpdate:render觸發之前觸發,更新群組件,不能修改屬性和狀態
④render:組件在render函數產生虛擬節點,最後由react將虛擬節點變成真正的節點渲染到頁面上,只能訪問this.props和this.state,只有一個頂層組件,最好不要修改狀態和DOM輸出。
⑤componentDidUpdate:render之後,真正的DOM被渲染之後調用
備忘:這五個函數的執行順序也是從上到下的。這個的測試代碼已上傳至:https://github.com/LuckyWinty/ReactStudyDemo,歡迎參考!

 銷毀階段:
①componentWillUnmount:這個函數在銷毀操作真正執行之前調用,給開發人員最後的機會進行一些清理工作。

三、屬性、狀態的含義和用法

屬性的含義:
props=properties,屬性是不可以由組件自己進行修改的,組件的屬性是由父組件傳遞進來的。
屬性的用法:
一)、索引值對

<Hello name="winty"/> 字串<Hello name={123}/> 大括弧包裹的求值運算式<Hello name={[1,2,3]}/> 傳入數組<Hello name={winty}/> 變數

二)、展開定義(個人認為就是對象式定義)

var props={ one:"123", two:"22"}

這樣定義的話,理論上使用應該是one={props.one}這樣調用,但是這樣寫起來比較繁瑣,而且如果資料被修改,就需要對應修改相應的賦值,並且無法動態地設定屬性,所以react中添加了一種展開文法:
<Hello {...props}/>    //也就是三個點加上對象名稱。
這樣使用展開文法,react就會自動把對象中的變數和值當作是屬性的賦值,所以Hello實際上就拿到了one、two兩個屬性,如果沒有三個點的話,Hello拿到的實際上就是props對象,使用的時候還需要自己從中取出變數和值
三)、調用react提供的setProps()函數(幾乎不用)

var instance=React.render(<HelloWorld></HelloWorld>,document.body);instance.setProps({name:"winty"});

狀態的含義:
state,狀態是由事物自行處理、不斷變化的
狀態的用法:
getInitialState:初始化執行個體的狀態
setState:更新群組件狀態,一旦更新了狀態,那麼就會觸發diff演算法,檢查內容是否發生變化,若有變化則更新群組件,否則就不用。 

屬性和狀態對比
相似點:都是純JS對象、都會觸發render更新、都具有確定性。


屬性和狀態區分:組件在運行時需要修改的資料就是狀態 

四、React中事件的用法
事件處理函數:React綁定事件處理器的方法和HTML文法非常類似,所有的事件在命名上與原生的javascript規範一致,並且會在相同的情境下觸發。
編寫函數
handleClick:function(){
...
}
綁定
onClick={this.handleClick} 

各類事件詳細說明:
①行動裝置上的觸摸事件:onTouchCancel、onTouchEnd、onTouchMove、onTouchStart
②鍵盤類事件:onKeyDown、onKeyPress、onKeyUp
③剪下類事件:onCopy、onCut、onPaste
④表單類:onChange//內容變化即觸發、onInput//輸入框、onSubmit//禁止表單預設跳轉行為
⑤事件:onFocus、onBlur
⑥UI元素類:onScroll
⑦滑鼠滾動事件:onWheel
⑧滑鼠類型:onClick、onContextMenu//右鍵菜單、onDoubleClick //雙擊、onMouseDown、onMouseEnter、onMouseLeave、onMouseMove、onMouseOut、onMouseOver、onMouseUp
⑨拖拽事件:onDrop、onDrag、onDragEnd、onDragEnter、onDragExit、onDragLeave、onDragOver、onDragStart
事件對象介紹
使用方法:就是在編寫事件對象處理函數的時候,添加一個參數。拿到這個對象之後,就通過對象的屬性來可以擷取一些資訊。
例如:

handleChange:function(event){ console.log(event.target.value);}

樣本中,event就是事件對象,event.target就是事件對象的屬性,就是對應的DOM元素,拿到這個元素之後再擷取它的值。
事件對象屬性
通用屬性:

 其他不同類型的事件有不同的屬性,簡單瞭解一下

知道了事件的一些屬性,我們就可以很方便地在React中擷取這些屬性,進行一些邏輯的處理,實現一些複雜的業務功能、頁面效果等。

例如:我們可以利用滑鼠事件屬性,即時顯示滑鼠在某個地區的座標:

<script type="text/jsx">  var HelloWorld = React.createClass({   getInitialState: function () {    return {     x: 0,     y: 0    }   },   handleMouseMove: function (event) {    this.setState({     x: event.clientX,     y: event.clientY    });   },   render: function () {    return <div onMouseMove={this.handleMouseMove} style={{     height: '500px',     width: '500px',     backgroundColor: 'gray'    }}>    {this.state.x + ', ' + this.state.y}    </div>;   },  });  React.render(<HelloWorld></HelloWorld>, document.body); </script>

x組件協同使用的定義:組件的協同本質上就是對組件的一種組織、管理方式。
組件協同使用的目的:邏輯清晰、代碼模組化、封裝細節、代碼可複用。
組件協同使用的方式:
①組件嵌套使用:也就是說,用一個父組件把子組件包裹起來,本質就是父子關係。如下圖描述:

執行個體代碼:

var React = require('react');var CommentList=require('./CommentList.jsx');var CommentForm=require('./commentFrom.jsx');var CommentBox = React.createClass({ render: function() { return (  <div className="commentBox">  <h1>Comments</h1>  <CommentList /> //這是一個組件  <CommentForm /> //這是另一個組件  </div> ); }});module.exports = CommentBox;

父子組件之間的通訊:
父組件->子組件:通過屬性,父組件把資料通過屬性來傳遞給子組件
子組件->父組件:本質上,子組件不能向父組件通訊。但是可以間接地通過觸發事件來通訊,也就是委託。
嵌套組合缺點:
父子關係的具體實現需要經過深思熟慮,貿然編寫將導致關係混亂、代碼難以維護
無法掌握所有細節,使用者只知道組件用法,不知道實現細節,遇到問題難以修複
②Mixin:也就是可以把相同的代碼抽象出來,封裝成一個函數,然後再調用。

Mixin的目的:橫向抽離出組件的相似代碼
相似概念:面向切向面編程、外掛程式
執行個體代碼:

var Time=React.createClass({ mixins:[IntervalMixin(1000)], getInitialState:function(){  return {secondElapsed:0}; }, onTick:function(){ this.setState({secondElapsed:this.state.secondElapsed+1}); }, render:function(){ return (  <div>Seconds Elapsed:{this.state.secondsElapsed}</div> ); }});

mixin相當簡單,它們就是混合進組件類中的對象而已。React在這方面實現得更加深入,它能防止靜默函數覆蓋,同時還支援多個mixin混合。但是這些功能在別的系統中可能引起衝突。例如:

React.createClass({ mixins:[{  getInitialState:function(){ return {a:1}} }], getInitialState:function(){ return {b:2}}});

這樣在mixin和組件類中同時定義了getInitialState方法,得到的初始state是{a:1,b:2}.如果mixin中的方法和組件類中的方法返回的對象中存在重複的鍵,React會拋出一個錯誤來警示這個問題。

 六、React中的雙向繫結

React創立的理念跟angular那些架構就是不同的,React是單向資料繫結的。那麼怎麼實現像angular那樣的雙向繫結效果呢?看代碼:

<!DOCTYPE html><html lang="zh-cn"><head> <meta charset="UTF-8"> <title>React中的雙向資料繫結</title></head><body> <script src="./react-0.13.2/react-0.13.2/build/react-with-addons.js"></script> <script src="./react-0.13.2/react-0.13.2/build/JSXTransformer.js"></script> <script type="text/jsx">  var BindingMixin = {   handleChange: function(key) {    var that = this    var newState = {}    return function(event) {      newState[key] = event.target.value     that.setState(newState)    }   }  }  var BindingExample = React.createClass({   mixins: [React.addons.LinkedStateMixin],   getInitialState: function() {    return {     text: '',     comment: '',    }   },   render: function() {    return <div>     <input type="text" placeholder="請輸入內容" valueLink={this.linkState('text')} />     <textarea valueLink={this.linkState('comment')}></textarea>     <h3>{this.state.text}</h3>     <h3>{this.state.comment}</h3>    </div>   }  })  React.render(<BindingExample></BindingExample>, document.body); </script></body></html>

效果圖(沒有CSS樣式,有點不優雅,見諒):

以上就是本文的全部內容,希望對大家的學習有所協助。

相關文章

聯繫我們

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