zoukankan      html  css  js  c++  java
  • React中setState 什么时候是同步的,什么时候是异步的?

    class Example extends React.Component {
      constructor() {
        super();
        this.state = {
          val: 0
        };
      }
      
      componentDidMount() {
        this.setState({val: this.state.val + 1});
        console.log(this.state.val);    // 第 1 次 log
    
        this.setState({val: this.state.val + 1});
        console.log(this.state.val);    // 第 2 次 log
    
        setTimeout(() => {
          this.setState({val: this.state.val + 1});
          console.log(this.state.val);  // 第 3 次 log
    
          this.setState({val: this.state.val + 1});
          console.log(this.state.val);  // 第 4 次 log
        }, 0);
      }
    
      render() {
        return null;
      }
    };

    先给出答案: 有时表现出异步,有时表现出同步
    1.setState只在合成事件和钩子函数中是“异步”的,在原生事件和setTimeout 中都是同步的。

    2.setState 的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,
    导致在合成事件和钩子函数中没法立马拿到更新后的值,形成了所谓的“异步”,当然可以通过第二个参数 setState(partialState, callback) 中的callback拿到更新后的结果。

    3.setState 的批量更新优化也是建立在“异步”(合成事件、钩子函数)之上的,在原生事件和setTimeout 中不会批量更新,
    在“异步”中如果对同一个值进行多次setState,setState的批量更新策略会对其进行覆盖,取最后一次的执行,如果是同时setState多个不同的值,在更新时会对其进行合并批量更新。

    在React中,如果是由React引发的事件处理(比如通过onClick引发的事件处理),调用setState不会同步更新this.state,除此之外的setState调用会同步执行this.state。所谓“除此之外”,指的是绕过React通过addEventListener直接添加的事件处理函数,还有通过setTimeout/setInterval产生的异步调用。

    **原因:**在React的setState函数实现中,会根据一个变量isBatchingUpdates判断是直接更新this.state还是放到队列中回头再说,而isBatchingUpdates默认是false,也就表示setState会同步更新this.state,但是,有一个函数batchedUpdates,这个函数会把isBatchingUpdates修改为true,而当React在调用事件处理函数之前就会调用这个batchedUpdates,造成的后果,就是由React控制的事件处理过程setState不会同步更新this.state。

    详细请看 https://github.com/LuNaHaiJiao/blog/issues/26

    好记性不如烂笔头,看到自己觉得应该记录的知识点,结合自己的理解进行记录,用于以后回顾。
  • 相关阅读:
    用同余理解补码
    objenesis
    spring 事务处理
    SOCKS5 协议解析
    WebSocket 的鉴权授权方案
    加密解密基础问题:字节数组和16进制字符串的相互转换
    主机字节序 与 网络字节序
    RSA 理论
    分类算法----k近邻算法
    R语言统计分析应用与SAS、SPSS的比较
  • 原文地址:https://www.cnblogs.com/wangxi01/p/11202501.html
Copyright © 2011-2022 走看看