本文主要是針對React的一些demo教程。參考了菜鳥教程中的react教程,作了一些總結。Demo的下載連接是javascript
https://github.com/RealAndMe/react-demo
下面要講解的例子都在對應的demo中。html
從github下載react-demo須要用到的命令行:java
#下載代碼 $ git clone git@github.com:RealAndMe/react-demo.git #安裝開發所依賴的模塊 $ npm install #運行並監聽 $ gulp watch #具體的能夠查看以前的相關博客
build文件夾裏是須要用到的js庫文檔react
每個demo文件夾都有
.html和.js
兩個文檔,其中js文檔中放的是主要的JSX功能,html是渲染的jquery
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title></title> <script src="../build/react.js"></script> <script src="../build/react-dom.js"></script> <script src="../build/browser.min.js"></script> </head> <body> <div id="contain"></div> <script type="text/babel" src="index.js"></script> </body> </html>
用到的React必須的庫:git
注意:React使用獨有的JSX,與javascript不兼容,因此凡是使用JSX的地方,都要加上
<script type="text/babel"></script>
github
這裏.js
後綴的文檔裏存放的是React的JSX語法,它是用來代替常規的javascript,執行速度更快。ajax
ReactDOM.render(<div>hello,world!</div>,document.getElementById("contain"));
ReactDOM.render()
方法是將JSX轉換爲HTML方法,並將其呈現到指定的DOM節點中,是React的基本語法。算法
JSX基本語法規則:遇到HTML標籤(以 < 開頭),就用HTML規則解析;遇到代碼塊(以 { 開頭),就用JavaScript規則解析。數據庫
上面代碼是將<div>
塊插入到contain
的節點中(查看demo01)
React.createClass()
方法生成一個React組件類,類名首字母必須大寫。(查看demo02)
每一個組件都有一個render : function(){}
的函數,用來輸出組件,而且函數裏都有return返回值。return裏描述的就是HTML樹結構,只能包含一個頂層標籤。。
<Demo02 />
實例化組件類並輸出信息。
var Demo02 = React.createClass({ render : function(){ return( <div className="demo02">hello,world!</div> ) } }); ReactDOM.render(<Demo02 />,document.getElementById("contain"));
能夠給標籤添加樣式,在html中添加類是class,可是在JSX中是calssName,而for屬性要寫成htmlFor,這是由於for和class是javascript的保留字。
在JSX中使用javascript的數組,樣式。(查看demo03)
咱們能夠添加內聯樣式。React會在指定元素數字後面自動添加px。
javascript代碼塊都要用花括號{ }
,註釋也須要寫在花括號中。
var array = ["lilei","wangdong","yulun"]; /*定義樣式*/ var myStyle = { fontSize: 100, color: "red", textAlign: "center" }; var Demo03 = React.createClass({ render : function(){ return( <div style={myStyle}> {/*遍歷數組*/} { array.map(function(msg,index){ return <div key={index}>hello,{msg}</div> }) } </div> ) } }); ReactDOM.render(<Demo03 />,document.getElementById("contain"));
數組遍歷的時候會有警告提示表示要加上一個key屬性,這個key是用來保證react-vdom標識的惟一性。
組件將具備屬性,可使用this.props.[attribute]
來訪問,attribute是對應的屬性的名稱。
(查看demo04)
var Demo04 = React.createClass({ render : function(){ return( <div>hello,{this.props.name}</div> ) } }); ReactDOM.render(<Demo04 name="wjy" />,document.getElementById("contain"));
上述代碼中就是經過this.props.name
獲取組件上的name屬性。
this.props.childre屬性表示組件的全部子節點。(查看demo05)
React.children.map(this.props.children,function(){})
方法用來遍歷子節點的。
var Demo05 = React.createClass({ render : function(){ return( <ol> { React.Children.map(this.props.children,function(msg){ return <li>{msg}</li> }) } </ol> ) } }); ReactDOM.render( <Demo05> <span>你好</span> <span>hello,world</span> </Demo05>, document.getElementById("contain") );
上述代碼中,組件<Demo05 />
中有兩個子節點,能夠經過this.props.children
來讀取。
this.props.children
的值有三種狀況:
因此要當心處理this.props.children屬性。
組件的屬性有不少種類型,好比:數值、字符串等,能夠經過React.propTypes來驗證props是否有效。當傳入的是無效的數據時,控制檯會拋出一個異常。(查看demo06)
//var flag = "字符串類型"; var flag = 123; var Demo06 = React.createClass({ propTypes : { title : React.PropTypes.string.isRequired }, render : function(){ return( <h1>{this.props.title}</h1> ) } }); ReactDOM.render(<Demo06 title={flag}/>,document.getElementById("contain"));
上述代碼中,組件<Demo06 />
有一個title
屬性,PropType
告訴React,title屬性是必須的,而且數據類型是字符串型。這裏咱們給title設置一個數值,這個時候屬性驗證不經過,控制檯會有一個異常信息。
getDefaultProps()方法是爲props設置默認值。(查看demo07)
var Demo07 = React.createClass({ getDefaultProps : function() { return{ title : "wangyu" } }, render : function(){ return( <h1>hello,{this.props.title}</h1> ) } }); ReactDOM.render(<Demo07 />,document.getElementById("contain"));
虛擬DOM:組件並非真實的 DOM 節點,而是存在於內存之中的一種數據結構。
只有在虛擬DOM插入到文檔以後,纔會變成真實DOM。
DOM diff算法:根據 React 的設計,全部的 DOM 變更,都先在虛擬 DOM 上發生,而後再將實際發生變更的部分,反映在真實 DOM上。這樣提升了網頁的性能表現。
從組件中獲取真實的DOM節點,使用ref
屬性。(查看demo08)
var Demo08 = React.createClass({ handleClick : function(){ /*用原生的方法focus()獲取文本框焦點*/ this.refs.textInput.focus(); }, render : function(){ // 當組件插入到 DOM 後,ref 屬性添加一個組件的引用於到 this.refs,這是在真實的Dom上進行的 return( <div> <input type="text" ref="textInput"/> <br/> <br/> <input type="button" value="點擊獲取焦點" onClick={this.handleClick}/> </div> ) } }); ReactDOM.render(<Demo08 / >, document.getElementById("contain"));
上述代碼中,<Dome08 />
組件有一個文本輸入框的子節點,用來獲取用戶的輸入。這時就必須獲取真實的 DOM 節點,虛擬 DOM 是拿不到用戶輸入的。爲了作到這一點,文本輸入框必須有一個 ref
屬性,而後 this.refs.[refName]
就會返回這個真實的 DOM 節點。
注意:由
於 this.refs.[refName]
屬性獲取的是真實 DOM ,因此必須等到虛擬 DOM 插入文檔之後,才能使用這個屬性,不然會報錯。
上面代碼中,經過爲組件指定 Click
事件的回調函數,確保了只有等到真實 DOM 發生 Click 事件以後,纔會讀取 this.refs.[refName]
屬性。
React將組件當作是一個狀態機,一開始有一個初始狀態,而後用戶互動,致使狀態變化,從而觸發從新渲染 UI (查看demo09)
var Demo09 = React.createClass({ getInitialState: function(){ return {like: false}; }, handleClick: function(){ this.setState({like:!this.state.like}); }, render: function() { var text = this.state.like?"喜歡":"不喜歡"; return ( <div> <p>我{text}你</p> <input value = "點擊切換狀態" type = "button" onClick = {this.handleClick}/> </div> ); } }); ReactDOM.render(<Demo09 />,document.getElementById("contain"));
上述代碼中,getInitialState()
方法定義state初始化的狀態,return返回的是一個對象。當用戶點擊按鈕,致使狀態改變時,this.setState({})
方法用來修改state狀態值,每次修改以後,都會自行調用this.render()
方法,再次渲染組件。
這個對象能夠經過this.state.[stateName]
屬性來獲取,stateName是定義的狀態的名稱。
this.props
表示那些一旦定義,就再也不改變的特性,而this.state
是會隨着用戶互動而產生變化的特性。
表單組件中的value屬性(好比:<input>,<textarea>,<option>,<select>
)不受任何用戶輸入的影響,若是要更新或訪問該值來響應用戶的輸入,那麼須要用onChange
事件來回調。(查看demo10)
var Demo10 = React.createClass({ getInitialState: function(){ return { value: "你好" }; }, handleChange: function(e){ this.setState({value: e.target.value}); }, render: function(){ var value = this.state.value; return ( <div> <input type="text" value={value} onChange={this.handleChange} /> <p>{value}</p> </div> ); } }); ReactDOM.render(<Demo10 />,document.getElementById("contain"));
上述代碼中,文本框輸入的值須要用 onChange
事件的回調函數,經過 event.target.value
讀取用戶輸入的值。textarea 元素、select元素、radio元素都屬於這種狀況
組件的生命週期有三個狀態:
Mounting
:已插入真實的DOMUpdating
:正在被從新渲染Unmounting
已移出真實的DOM生命週期的方法總共有7種:
will
函數在進入狀態以前調用,did
在進入狀態以後調用。
componentWillMount
在渲染以前調用componentDidMount
在第一次渲染以後調用。以後組件已經生成了對應的DOM結構,能夠經過this.getDOMNode()來進行訪問。 若是你想和其餘JavaScript框架一塊兒使用,能夠在這個方法中調用setTimeout, setInterval或者發送AJAX請求等操做(防止異部操做阻塞UI)。componentWillReceiveProps
組件接收到新的prop時調用,在初始化render時不調用。shouldComponentUpdate
組件判斷是否須要從新渲染時componentWillUpdate
組件在接收到新的prop或state但尚未渲染時componentDidUpdate
組件完成更新後調用componentWillUnmount
組件在DOM移出後調用var Demo11 = React.createClass({ getDefaultProps: function(){ return {name: "wjy"}; }, getInitialState: function () { return {opacity: 1.0}; }, componentDidMount: function () { setInterval(function () { var opacity = this.state.opacity; opacity -= .05; if (opacity < 0.1) { opacity = 1.0; } this.setState({ opacity: opacity }); }.bind(this), 100); }, render: function () { return ( <div style={{opacity: this.state.opacity}}> Hello {this.props.name} </div> ); } }); ReactDOM.render(<Demo11 />,document.getElementById("contain"));
在組件<Demo11 />
加載完以後,經過該componentDidMount
方法設置setInterval(function(){},time)
定時器,每100ms從新設置組件透明度,而後從新渲染。(查看demo11)
其中給函數加上
bind(this)
是爲了給當前的對象綁定事件,防止出錯
組件的樣式要注意,React 組件樣式是一個對象,因此第一重大括號表示這是 JavaScript 語法,第二重大括號表示樣式對象
style={{opacity: this.state.opacity}} //正確寫法
React 組件的數據能夠經過 componentDidMount
方法中的 Ajax 來獲取,當從服務端獲取數據庫能夠將數據存儲在 state 中,再用 this.setState
方法從新渲染 UI。(查看demo12)
var Demo12 = React.createClass({ getInitialState: function() { return { username: '', lastGistUrl: '' }; }, componentDidMount: function() { /* *jquery ajax——get()方法經過遠程HTTP GET請求載入信息,取代複雜$.ajax $.get(this.props.source,function(data){ var lastGist = data[0]; if(this.isMounted()){ this.setState({ username: lastGist.owner.login, lastGistUrl: lastGist.html_url }); }; }.bind(this));*/ $.ajax({ url: this.props.source, type: "get", success: function(data){ var lastGist = data[0]; if(this.isMounted()){ this.setState({ username: lastGist.owner.login, lastGistUrl: lastGist.html_url }); }; }.bind(this) }); }, render: function() { return ( <div> {this.state.username}用戶最新的共享地址: <a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a> </div> ); } }); ReactDOM.render(<Demo12 source="https://api.github.com/users/octocat/gists"/>,document.getElementById("contain"));
$
上述代碼中,利用了jQuery的ajax()方法來獲取服務器端的數據,也能夠經過jquery的ajax的$.get(url,data,sucess(),dataType)
方法經過遠程HTTP GET請求載入信息,取代複雜$.ajax。
注意:在函數中常常會用到
bind(this)
,這裏的this指向就是componentDidMount()
中的this也就是這個react對象,這樣纔可以正確訪問react屬性方法this.state,this.setState
等
JSX 容許直接在模板插入 JavaScript 變量。若是這個變量是一個數組,則會展開這個數組的全部成員。查看demo13)
var Demo13 = React.createClass({ render: function() { var array = [ <h1>你好!</h1>, <h2>hello,world!</h2> ]; return ( <div>{array}</div> ); } }); ReactDOM.render(<Demo13 />,document.getElementById("contain"));
上面代碼的array變量是一個數組,結果 JSX 會把它的全部成員,添加到模板中。
有道雲筆記參考:http://note.youdao.com/noteshare?id=93e15b78b01eca521abc083659c7f356&sub=4CA29FC7AE614755889C60A513DDAF44