文章出處

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是

  1. Preserving the input selection ranges before/after reconciliation.
    Restoring selection even in the event of an unexpected error.
  2. Deactivating events while rearranging the DOM, preventing blurs/focuses,
    while guaranteeing that afterwards, the event system is reactivated.
  3. Flushing a queue of collected DOM mutations to the main UI thread after a
    reconciliation takes place in a worker thread.
  4. Invoking any collected componentDidUpdate callbacks after rendering new
    content.
  5. (Future use case): Wrapping particular flushes of the ReactWorker queue
    to preserve the scrollTop (an automatic scroll aware DOM).
  6. (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更新。
更詳細的流程參考此圖
react事件回調核心流程

3.參考文章(強烈推薦去看)

http://undefinedblog.com/what-happened-after-set-state/
http://zhuanlan.zhihu.com/purerender/20328570


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()