1.兩個示例
- 示例1
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 2
- 示例2
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。
2.解釋
首先介紹React的Transaction。
其源碼在React/lib/Transaction.js。
Transaction就是給需要執行的方法fn用wrapper封裝了 initialize 和 close 方法。且支持多次封裝。再通過 Transaction 提供的 perform 方法執行。 perform執行前,調用所有initialize 方法。perform 方法執行后,調用所有close方法。
Transaction的use case是
- Preserving the input selection ranges before/after reconciliation.
Restoring selection even in the event of an unexpected error. - Deactivating events while rearranging the DOM, preventing blurs/focuses,
while guaranteeing that afterwards, the event system is reactivated. - Flushing a queue of collected DOM mutations to the main UI thread after a
reconciliation takes place in a worker thread. - Invoking any collected
componentDidUpdate
callbacks after rendering new
content. - (Future use case): Wrapping particular flushes of the
ReactWorker
queue
to preserve thescrollTop
(an automatic scroll aware DOM). - (Future use case): Layout calculations before and after DOM updates.
示例一,對應的是第4點use case。整個生命周期就是一個Transaction,在Transaction執行期間,componentDidUpdate方法被推入一個隊列中。DOM reconciliation后,再調用隊列中的所有componentDidUpdate。
示例二,對應的是第3點use case。react的事件回調也是一個Transaction。handleClick里面的this.setState不會馬上生效,而是先通過 ReactUpdates.batchedUpdate 方法存入臨時隊列。所以每次setState時,拿到的this.state.clicked都是初始值。直到transaction 完成,通過ReactUpdates.flushBatchedUpdates方法進行UI更新。
更詳細的流程參考此圖
3.參考文章(強烈推薦去看)
http://undefinedblog.com/what-happened-after-set-state/
http://zhuanlan.zhihu.com/purerender/20328570
文章列表