zoukankan      html  css  js  c++  java
  • React的Transaction浅析

    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

  • 相关阅读:
    Django基础之cookie
    Django基础之redirect()
    Django基础之render()
    Django基础之JsonResponse对象
    Django基础之response对象
    scrapy框架自定制命令
    数据分析案例-拉勾网招聘信息
    爬虫之单线程多任务异步抓取
    数据分析之matplotlib使用
    数据分析之numpy使用
  • 原文地址:https://www.cnblogs.com/samwu/p/5024790.html
Copyright © 2011-2022 走看看