本篇會簡明扼要的介紹一下React的使用方法。代碼會用JSX+ES5和JSX+ES6兩種方式實現。 javascript
React來自Facebook,於2013年開源。至今不斷修改完善,如今已經到達了版本0.14.2。能夠注意到版本尚未到1.0, 廣泛應用到大部分產品中還須要必定的時間。2015年3月份,FaceBook發佈了React Native,一個用react來構建native app的框架。
步入正題,React是一個javascript的類庫,用於構建用戶界面。php
JUST THE UI
不一樣於Angularjs框架,React不屬於MVC框架,它能夠算是MVC裏面的V層,因此相對來講入門也簡單一下(只指入門,深度研究的話也不簡單)。css
DATA FLOW
React是單向響應的數據流。html
一種特殊的js語法,能夠在js代碼中直接使用html標籤。是個語法糖,提升編寫代碼效率。
要注意不能在標籤的中間添加註釋,由於最終仍是要翻譯成原生js,標籤中添加註釋至關於在一行代碼還沒完的時候就添加註釋。
在jsx中,變量用花括號包圍起來,花括號內的語句將以js代碼的方式解析。
例如:java
// 用純js在react中建立a標籤 var newDom=<React.createElement('a', {href: 'https://facebook.github.io/react/'}, 'Hello!');
// 用jsx在react中建立a標籤 var newDom=<a href="https://facebook.github.io/react/">Hello!</a>;
要讓瀏覽器認識這種新的語法,就須要下面介紹的babel了。react
是一個javascript代碼轉換器,在這裏咱們能夠用於jsx轉換爲原生js,es6轉換爲es5(大部分都能轉換)。固然它的功能不僅這些,有興趣的能夠去babel官網看看。它還有個線上的轉換器,代碼比較簡單的時候用這個排查問題或練習es6很方便。
介紹兩種經常使用的使用方式:webpack
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
//在webpack.config.js文件中配置 module.exports = { module: { loaders: [{ test: /\.jsx?$/, loader: 'babel' }] } }
能夠在本地編譯好代碼後,再將編譯後的代碼給html引用,提升性能,適合大項目。git
一個模塊打包工具,它把不一樣的、相互依賴的靜態資源都視做模塊,而且打包成咱們想要的靜態資源。
另外能夠方便的配置多種預處理器,如babel。
使用webpack,讓代碼組織更清晰,一個文件就是一個模塊。es6
ES6,也叫ECMAScript2015(如下統稱ES6),是ECMAScript標準的最新版本。詳細可見ES6的特性簡述(譯+部分解析)github
<!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>
通常從定義到使用組件的流程是:定義組件creatClass,實現render方法->將組件渲染到頁面ReactDOM.render()。
ReactElement對象能夠當作是虛擬DOM樹。它既是渲染組件ReactDOM.render(root,container)的第一個參數,又是建立組件React.createClass中render方法的返回值。記住ReactElement是惟一父節點的’dom樹‘就好。
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/react/'}, 'Hello!');
<a href=''>Hello</a>
react-dom模塊中的方法。
ReactDom.render(root, container);
root爲ReactElement類型,表示root替換container中的元素。注意是替換不是追加,因此有些狀況父元素應該設置爲空。
var content=React.createElement('h1',{},'hello'); ReactDOM.render(content,document.getElementById('example'));
ReactDOM.render(<h1>hello word!</h1>,document.getElementById('example'));
組件是一個自定義的js對象,在es5中使用React.createClass();在es6中必須繼承React.component。
其中有個特殊的render方法,返回ReactElement對象。該方法會在咱們使用JSX語法的標籤
如:ReactDOM.render(<MyElement />,document.getElementById('example'))
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') );
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') );
一個js對象,對應於dom的屬性。
<a className="center"></a>
<a style={{backgroundImage: 'url(' + imgUrl + ')',font:'12px'}}></a>
<a newProp="propValue"></a>
。這樣就能夠在this.props['newProp']中讀取值var NewDom = React.createClass({//類名必定要大寫開頭 getDefaultProps: function() {//設置默認屬性 return {title:'133'}; }, propTypes: { title:React.PropTypes.string, },//屬性校驗器,表示必須是string render: function() { return <div>{this.props.title}</div>;//變量用花括號標識 } });
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'};//設置默認屬性
一個js對象,存儲着組件當前的狀態以及其值的集合。
我的以爲這也是react的創新點之一,能夠把組件當作一個「狀態機」. 根據不一樣的status有不一樣的UI展現。只要使用setState改變狀態值,根據diff算法算出來有差之後,就會執行ReactDom的render方法,從新渲染頁面。
這避免了開發者直接操做dom對象已達到從新渲染頁面。開發者只須要關注state這個中間人,控制它就能夠控制頁面刷新。第二篇中評論框的渲染就是使用的state來控制。
是否是感受和props有些相似?通常區分兩個的原則是,可變的放在state中,不可變的放在props中。
class *** extends React.Component{ getInitialState: function() { return {liked: false}; } }
class *** extends React.Component{ constructor(props) { super(props); this.state = {liked: false}; } }
this.setState(新的state對象);
事件名
和屬性名相似,到了react中,事件名也成了駝峯命名法,好比onclick變爲了onClick.
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>;//變量用花括號標識 } });
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 } }
handleChange: function(event) { this.setState({value: event.target.value});//event.target.value元素的值 }
每一個控件取值不同,value是指input控件,下拉框爲selected,radiobutton爲checked。a標籤是innerHtml。能夠本身經過console.info(e.target) 調試出本身想要的那個字段
render() {//開頭花括號必定要和小括號隔一個空格,不然識別不出來 return <ol>//標籤前一半必定要和return一行 { React.Children.map(this.props.children, function (child) { return <li>{child}</li>; }) } </ol>; }
onClick={this.func1.bind(this)}
。通過這番簡單的練習後,若是還想看看作一個項目中如何使用react參見下章,一個模仿微博展現的demo(編寫ing)。 本文沒有對react做深刻的研究。經過學習react的使用方法能夠看到,react入門的話相對於其餘框架仍是比較簡單的,代碼邏輯也很清晰,好維護也好使用。重要的是,須要使用者把從前直接對dom操做的思惟方式轉換過來,相信會愛上它的。 ps: react 還在發展期,學習的話建議英語好的直接看官方文檔,能夠少走一些彎路。