React入門 (1)—使用指南(包括ES5和ES6對比)

前言
  本篇會簡明扼要的介紹一下React的使用方法。代碼會用JSX+ES5和JSX+ES6兩種方式實現。  javascript

React簡介  
  React來自Facebook,於2013年開源。至今不斷修改完善,如今已經到達了版本0.14.2。能夠注意到版本尚未到1.0, 廣泛應用到大部分產品中還須要必定的時間。2015年3月份,FaceBook發佈了React Native,一個用react來構建native app的框架。
  步入正題,React是一個javascript的類庫,用於構建用戶界面。css

三個特色html

JUST THE UI
  不一樣於Angularjs框架,React不屬於MVC框架,它能夠算是MVC裏面的V層,因此相對來講入門也簡單一下(只指入門,深度研究的話也不簡單)。java

VIRTUAL DOM——虛擬DOM
  虛擬dom實際上是輕量的js對象,只保留了原生dom的一些經常使用的屬性和方法。
自定義標籤
  學習React須要有一種全新的思路去看待view層的構建。除了使用html原生的標籤,開發者還能夠自定義標籤(即虛擬DOM,最終給瀏覽器渲染的時候會解析成原生dom),天然代碼解耦的效果會很明顯,也更易讀。
性能提高
  在你們優化代碼性能的時候,必定會關注有沒有多餘的dom操做,這是由於dom相關的操做耗時比較長。就算是建立一個空標籤,也許要初始化它的各類默認屬性和事件。
  React渲染頁面並不直接操做dom,而是先經過diff算法比較先後虛擬dom的差別。這最大程度的簡化dom操做,大大提升了性能。因爲只是局部更新dom,因此只是局部刷新。
  換而言之,虛擬dom的出現,是由於目前js的性能比DOM渲染的性能要好,因此能夠用更多的js操做換取更少的dom操做。也不排除若是未來有一天dom的性能和js差很少的時候,虛擬dom也許就沒那麼大的意義了。
DATA FLOW
React是單向響應的數據流。react

React相關知識簡介
jsxwebpack

  一種特殊的js語法,能夠在js代碼中直接使用html標籤。是個語法糖,提升編寫代碼效率。
  要注意不能在標籤的中間添加註釋,由於最終仍是要翻譯成原生js,標籤中添加註釋至關於在一行代碼還沒完的時候就添加註釋。
  在jsx中,變量用花括號包圍起來,花括號內的語句將以js代碼的方式解析。
  例如:git

// 用純js在react中建立a標籤
var newDom=<React.createElement('a', {href: 'https://facebook.github.io/re...'}, 'Hello!');
// 用jsx在react中建立a標籤
var newDom=Hello!;
  要讓瀏覽器認識這種新的語法,就須要下面介紹的babel了。es6

babelgithub

   是一個javascript代碼轉換器,在這裏咱們能夠用於jsx轉換爲原生js,es6轉換爲es5(大部分都能轉換)。固然它的功能不僅這些,有興趣的能夠去babel官網看看。它還有個線上的轉換器,代碼比較簡單的時候用這個排查問題或練習es6很方便。
  介紹兩種經常使用的使用方式:web

一種是瀏覽器來編譯,由於實時編譯會很慢,因此適合代碼量比較小的。只需在html中引用:
<script src="https://cdnjs.cloudflare.com/...
一種是本地使用。經過npm安裝,在webpack中配置:
//在webpack.config.js文件中配置
module.exports = {

module: {
    loaders: [{
    test: /\.jsx?$/,
    loader: 'babel'
    }]
}

}
  能夠在本地編譯好代碼後,再將編譯後的代碼給html引用,提升性能,適合大項目。

webpack

  一個模塊打包工具,它把不一樣的、相互依賴的靜態資源都視做模塊,而且打包成咱們想要的靜態資源。
  另外能夠方便的配置多種預處理器,如babel。
  使用webpack,讓代碼組織更清晰,一個文件就是一個模塊。

ES6

  ES6,也叫ECMAScript2015(如下統稱ES6),是ECMAScript標準的最新版本。詳細可見ES6的特性簡述(譯+部分解析)

搭建簡單的運行環境
方式一:直接引入react、reactdom、babel的庫。
  由於這種方式是瀏覽器負責即時編譯的,因此可想而知項目大了得時候解析速度會很慢,不建議使用。可是咱們只是學習react語法嘛,固然要搭的環境越簡單越好。
  這種方式就是官網給出的實例所使用的方式。注意寫jsx的的js塊的type="text/babel",這樣才能被瀏覽器識別並用babel編譯。
  如下是本章要用到的代碼框架(一個helloword的demo) :
<!DOCTYPE html>
<html>
<head>

<meta charset="utf-8">
<title>demo</title>

</head>
<body>

<div id='example'></div>
<script src="./build/react.js"></script>
<script src="./build/react-dom.js"></script>
<script src="./build/browser.min.js"></script>
<script type="text/babel">
  // react代碼寫到這裏
  ReactDOM.render(<h1>hello word!</h1>,document.getElementById('example'));
</script>

</body>
</html>
方式二:使用npm + webpack
  篇幅限制,下篇說,歡迎看第二篇。
學會react的基本語法
  通常從定義到使用組件的流程是:定義組件creatClass,實現render方法->將組件渲染到頁面ReactDOM.render()。

建立ReactElement

  ReactElement對象能夠當作是虛擬DOM樹。它既是渲染組件ReactDOM.render(root,container)的第一個參數,又是建立組件React.createClass中render方法的返回值。記住ReactElement是惟一父節點的’dom樹‘就好。

react原生實現
React.createElement(
string/ReactClass type, //type組件類型能夠是內置的標籤,如div;也能夠是由React.createClass(object specification)建立的虛擬組件
[object props], // 標籤屬性,數組
[children ...],// 標籤的innerHtml
)//返回類型是ReactElement
var newDom=React.createElement('a', {href: 'https://facebook.github.io/re...'}, 'Hello!');
jsx實現
Hello
把組件渲染到瀏覽器中

  react-dom模塊中的方法。
  ReactDom.render(root, container); root爲ReactElement類型,表示root替換container中的元素。注意是替換不是追加,因此有些狀況父元素應該設置爲空。

react原生
var content=React.createElement('h1',{},'hello');
ReactDOM.render(content,document.getElementById('example'));
jsx
ReactDOM.render(<h1>hello word!</h1>,document.getElementById('example'));
建立組件

  組件是一個自定義的js對象,在es5中使用React.createClass();在es6中必須繼承React.component。
  其中有個特殊的render方法,返回ReactElement對象。該方法會在咱們使用JSX語法的標籤時被調用,所以咱們在渲染組件時第一個參數可使用自定義標籤或者createElement。
  如:ReactDOM.render(<MyElement />,document.getElementById('example'))     

es5
var NewDom = React.createClass({//類名必定要大寫開頭

render: function() {
    return (
        <ol>
          {
            React.Children.map(this.props.children, function (child) {
              //得到元素的子元素
              console.info(this);
              console.info('child:'+child);
              return <li>{child}</li>;//變量用花括號標識
            })//由於有多個子元素,因此返回的是數組。按照JSX變量是數組來解析。
          }
        </ol>
   );
}

});
ReactDOM.render(

<NewDom>
    <span>lala</span>
    <span>ass</span>
</NewDom>,
 document.getElementById('example')

);
es6
class NewDom extends React.Component{

render() {//開頭花括號必定要和小括號隔一個空格,不然識別不出來
    return <ol>//標籤開頭必定要和return一行
      {
         React.Children.map(this.props.children, function (child) {
               return <li>{child}</li>;
         })
      }
    </ol>;
}

}
ReactDOM.render(

<NewDom>
    <span>lala</span>
    <span>ass</span>
</NewDom>,
 document.getElementById('example')

);
組件的屬性props

一個js對象,對應於dom的屬性。

原生屬性
某些html的屬性名由於正好是js得保留字,因此須要從新命名。
class
由於js中class爲保留字,因此要寫成className。

style
style屬性接受由css屬性構成的js對象。對於jsx來講第一是變量,第二是對象,所以要兩個花括號,key值用駝峯命名法轉化了,value值用引號括起來

新增屬性
this.props.children 表示組件的全部子節點,上一小節的示範代碼中有介紹
傳遞屬性值
在ReactDOM.Render第一個參數中直接寫入帶屬性的標籤便可: 。這樣就能夠在this.props['newProp']中讀取值
設置默認屬性
在ES6中爲屬性:defaultProps(能夠標識static定義在class內,也能夠定義在class外)
在ES5中爲方法:getDefaultProps: function(){return {name:value}};
屬性的讀取
this.props['propName']得到屬性
新增功能:屬性校驗器propTypes
見代碼示例
代碼示範
es5
var NewDom = React.createClass({//類名必定要大寫開頭

getDefaultProps: function() {//設置默認屬性
   return {title:'133'};
},
propTypes: {
   title:React.PropTypes.string,
},//屬性校驗器,表示必須是string
render: function() {
   return <div>{this.props.title}</div>;//變量用花括號標識
}

});
es6
class NewDom extends React.Component{
//不能再組件定義的時候定義一個屬性
render() {

return <div >1{this.props.title}</div>;

}//開頭花括號必定要和小括號隔一個空格,不然識別不出來
}
//es6 這兩個屬性不能寫在class內。
NewDom.propTypes={//屬性校驗器,表示改屬性必須是bool,不然報錯
title: React.PropTypes.bool,
}
NewDom.defaultProps={title:'133'};//設置默認屬性
組件的狀態state

  一個js對象,存儲着組件當前的狀態以及其值的集合。
  我的以爲這也是react的創新點之一,能夠把組件當作一個「狀態機」. 根據不一樣的status有不一樣的UI展現。只要使用setState改變狀態值,根據diff算法算出來有差之後,就會執行ReactDom的render方法,從新渲染頁面。
  這避免了開發者直接操做dom對象已達到從新渲染頁面。開發者只須要關注state這個中間人,控制它就能夠控制頁面刷新。第二篇中評論框的渲染就是使用的state來控制。
  是否是感受和props有些相似?通常區分兩個的原則是,可變的放在state中,不可變的放在props中。 

初始化
es5
class * extends React.Component{
getInitialState: function() {

return {liked: false};

}
}
es6
class * extends React.Component{
constructor(props) {

super(props);
this.state = {liked: false};

}
}
修改值
es5和es6中使用方法相同。
this.setState(新的state對象);
讀取值
其實就是讀取一個js對象。
事件

事件名
和屬性名相似,到了react中,事件名也成了駝峯命名法,好比onclick變爲了onClick.

事件定義
必定要注意es6中元素如何使用自定義事件。見代碼。
es5
var NewDom = React.createClass({//類名必定要大寫開頭

btnClick:function(ele){
   console.info(ele);
   console.info(this.refs.tex);
},
render: function() {
   return <div >
      <input type="text" ref="tex" />
      <input type="button" onClick={this.btnClick} value='click me' />
   </div>;//變量用花括號標識
}

});
es6
class NewDom extends React.Component{

btnClick(){
    console.info(this);//this爲該組件類
    console.info(this.refs.tex);//this.refs.tex爲組件裏面索引爲tex的
}
render() {
    return <div >
        <input type="text" ref="tex" />
        <input type="button" onClick={this.btnClick.bind(this)} value='click me' />
    </div>;//注意bind後面的this
}

}
事件target
下面是一個事件對應要執行的函數的定義:
handleChange: function(event) {

this.setState({value: event.target.value});//event.target.value元素的值

}
每一個控件取值不同,value是指input控件,下拉框爲selected,radiobutton爲checked。a標籤是innerHtml。能夠本身經過console.info(e.target) 調試出本身想要的那個字段

ES6的坑
類名(組件名)必定要用大寫開頭,不然自定義的組件沒法編譯,識別不出來。
類中定義render函數要注意兩點,見代碼註釋。
render() {//開頭花括號必定要和小括號隔一個空格,不然識別不出來
return <ol>//標籤前一半必定要和return一行

{
    React.Children.map(this.props.children, function (child) {
       return <li>{child}</li>;
    })
  }

</ol>;
}
在class中使用class的變量或者方法,必定要加個this。如this.handlerclick。
es6 綁定事件須要onClick={this.func1.bind(this)}。
這樣func1和bind裏面的參數‘this’的做用域才綁定到了一塊兒(注意es5是不須要這個bind(this)的),func1中若是有this.name這類語句,至關因而使用參數‘this’裏面的變量值;或者使用箭頭函數func1= (e)=> {函數體}
小結
  通過這番簡單的練習後,若是還想看看作一個項目中如何使用react參見下章,一個模仿微博展現的demo(編寫ing)。
  本文沒有對react做深刻的研究。經過學習react的使用方法能夠看到,react入門的話相對於其餘框架仍是比較簡單的,代碼邏輯也很清晰,好維護也好使用。重要的是,須要使用者把從前直接對dom操做的思惟方式轉換過來,相信會愛上它的。
  ps: react 還在發展期,學習的話建議英語好的直接看官方文檔,能夠少走一些彎路。
本文轉載自 http://www.cnblogs.com/Mrs-cc...

相關文章
相關標籤/搜索