let SonClass = React.createClass({ render: function(){ console.log("render", this.props.num); return null; }, componentDidMount: function(){ console.log('componentDidMount', this.props.num); } }); let FatherClass = React.createClass({ render:function(){ return ( <div> <SonClass num="one" /> <SonClass num="two" /> </div> ) } }); ReactDOM.render( <FatherClass /> , document.getElementById("test") );
輸出爲
render 2
componentDidMount 2javascript
let React = require('react'); let ReactDOM = require('react-dom'); let Hello = React.createClass({ getInitialState: function() { return { clicked: 0 }; }, handleClick: function() { this.setState({ clicked:this.state.clicked + 1 }); this.setState({ clicked: this.state.clicked + 1 }); }, render: function() { return <button onClick = { this.handleClick } > { this.state.clicked } </button>; } }); ReactDOM.render( <Hello /> , document.getElementById("test") );
點擊後this.state.clicked遞增1,而不是遞增2。java
首先介紹React的Transaction。
其源碼在React/lib/Transaction.js。
Transaction就是給須要執行的方法fn用wrapper封裝了 initialize 和 close 方法。且支持屢次封裝。再經過 Transaction 提供的 perform 方法執行。 perform執行前,調用全部initialize 方法。perform 方法執行後,調用全部close方法。react
Transaction的use case是app
componentDidUpdate
callbacks after rendering newReactWorker
queuescrollTop
(an automatic scroll aware DOM).示例一,對應的是第4點use case。整個生命週期就是一個Transaction,在Transaction執行期間,componentDidUpdate方法被推入一個隊列中。DOM reconciliation後,再調用隊列中的全部componentDidUpdate。dom
示例二,對應的是第3點use case。react的事件回調也是一個Transaction。handleClick裏面的this.setState不會立刻生效,而是先經過 ReactUpdates.batchedUpdate 方法存入臨時隊列。因此每次setState時,拿到的this.state.clicked都是初始值。直到transaction 完成,經過ReactUpdates.flushBatchedUpdates方法進行UI更新。
更詳細的流程參考此圖
ui
http://undefinedblog.com/what-happened-after-set-state/
http://zhuanlan.zhihu.com/purerender/20328570this