最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • React setState 同步or异步?

    正文概述 掘金(Smile月芽儿ˇ◡ˇ)   2020-12-09   318
    1. setState 在生命周期和合成事件中是异步;在原生事件和异步方法里是同步;(异步方法里主要是涉及到js事件循环的宏任务和微任务。)

    2. setState 异步实际上是生命周期和合成事件在更新之前被调用,导致他们拿到的数据不是更新后的值。

    3. setState 在生命周期和合成事件中会进行批量更新优化,即对同一个key进行多次setState,只取最后一次执行。如果是更新多个key,在更新时合并批量更新。

    合成事件、生命周期的setState

    这两段代码表明在合成事件和生命周期里,setState是异步的,并且多次setState只会更新最后一个设置的值。

    // 代码1
    import React, { Component } from "react";
    
    export default class App extends Component {
      state = {
        count: 0,
      };
    
      changeCount = () => {
        console.info(this.state.count); // 0
        this.setState({
          count: 1,
        });
        this.setState({
          count: 3,
        });
        console.info(this.state.count); // 0
      };
    
      render() {
        return (
          <div>
            <button onClick={this.changeCount}> 点击</button>
            渲染结果等于3 {this.state.count}
          </div>
        );
      }
    }
    
    // 代码2
    import React, { Component } from "react";
    
    export default class App extends Component {
      state = {
        count: 0,
      };
    
      componentDidMount() {
        console.info(this.state.count); // 0
        this.setState({
          count: 1,
        });
        this.setState({
          count: 3,
        });
        console.info(this.state.count); // 0
      }
    
      render() {
        return <div>渲染结果等于3 {this.state.count}</div>;
      }
    }
    

    原生事件里的setState

    import React, { Component } from "react";
    
    export default class App extends Component {
      state = {
        count: 0,
      };
    
      changeCount = () => {
        console.info(this.state.count); // 0
        this.setState({
          count: this.state.count + 1,
        });
        console.info(this.state.count); // 1
      };
    
      componentDidMount() {
        document.getElementById("btn").addEventListener("click", this.changeCount);
      }
    
      render() {
        return (
          <div>
            <button id="btn">点击{this.state.count}次</button>
          </div>
        );
      }
    }
    

    异步函数中的setState

    import React, { Component } from "react";
    
    export default class App extends Component {
      state = {
        count: 0,
      };
    
      componentDidMount() {
        setTimeout(() => {
          console.info(this.state.count); // 0
          this.setState({ count: this.state.count + 1 });
          console.info(this.state.count); // 1
        }, 0);
      }
    
      render() {
        return <div> {this.state.count}</div>;
      }
    }
    

    练习题

    最后来看下,这段代码的输出结果:

    import React, { Component } from "react";
    
    export default class App extends Component {
      state = {
        count: 0,
      };
      componentDidMount() {
        this.setState({ count: this.state.count + 1 });
        console.log("origin1", this.state.count); // 0  step1
        this.setState({ count: this.state.count + 1 });
        console.log("origin2", this.state.count); // 0 step2
        setTimeout(() => {
          console.log("timeout start", this.state.count); // 3 step9
          this.setState({ count: this.state.count + 1 });
          console.log("timeout1", this.state.count); // 4 step10
          this.setState({ count: this.state.count + 1 });
          console.log("timeout2", this.state.count); // 5 step11
        }, 1000);
    
        new Promise((reslove) => {
          console.log("Promise start", this.state.count); //0 step3
          this.setState({ count: this.state.count + 1 });
          console.log("Promise1", this.state.count); // 0 setp4
          reslove({});
          this.setState({ count: this.state.count + 1 });
          console.log("Promise2", this.state.count); // 0 setp5
        }).then(() => {
          console.log("then", this.state.count); // 1 setp6
          this.setState({ count: this.state.count + 1 });
          console.log("then1", this.state.count); // 2 setp7
          this.setState({ count: this.state.count + 1 });
          console.log("then2", this.state.count); // 3 setp8
        });
      }
      render() {
        return <div>setState {this.state.count}</div>;
      }
    }
    

    起源地下载网 » React setState 同步or异步?

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元