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