React——setState 是同步还是异步问题

这篇是为了了解清楚setState的更新机制,有人理解setState方法是异步的,但这个是错误的!!

setState方法是异步的嘛?
// 从这里我们可以看到,打印出来是1,会以为setState是异步的
this.state = { count: 1 }
this.setState({
	count: this.state.count + 1
})
console.log(this.state.count) // 1

​ 我们试下看,调用setState多次,会执行几次。

// 这里可以看到最后结果,count只会是2
this.state = { count: 1 }
this.setState({
	count: this.state.count + 1
})
this.setState({
	count: this.state.count + 1
})
this.setState({
	count: this.state.count + 1
})
console.log(this.state.count) // 1

​ 从这里我们可以看出来,我们调用多少次setState,不会依次执行,会把所有对象合并到state,再促发组件更新,只会触发一次重新渲染,减少re-render调用。这是React内部性能优化机制,类似异步效果而已,但它不是异步!

如何解决setState合并执行的问题?(解决多次调用依赖,同步)

上面使用的都是对象去设置state的内容,那如果我们通过updater函数的形式去改变

updater函数:setState((preState) => {}) 语法

updater函数:setState((preState) => {},callback 语法,第二个参数callback是再setState执行完毕(页面渲染完毕)后执行

​ 通过使用updater函数,我们多次调用setState的时候,每次都返回最新的State,解决上面的问题

this.setState((preState) => {
    return {
    	count: preState.count + 1
    }
})
console.log(this.state.count) // 1
总结:setState是React性能优化机制——同步!!

从前面我们可以看到setState的表现都很像异步,但本身并不是一个异步方法,是同步的!!

​ 如果setState是一个同步执行的机制,那么这个组件会被重新渲染100次,这对性能是一个相当大的消耗。

React框架设计的性能优化机制,在React环境中,setState表现出来是异步的;

在原生事件、setTimeout/setInterval、async/await,setState表现出来是同步的;

setState本身并不是异步,只是因为react的性能优化机制体现为异步。在react的生命周期函数或者作用域下为异步,在原生的环境下为同步。

// 同步 例子1 原生事件
state = {
    number:1
};
componentDidMount() {
    document.body.addEventListener('click', this.changeVal, false);
}
changeVal = () => {
    this.setState({
      number: 3
    })
    console.log(this.state.number)
}

// 同步 例子2 setTimeout
state = {
    number:1
};
componentDidMount(){
    setTimeout(()=>{
      this.setState({number:3})
      console.log(this.state.number)
    },0)
}

相关推荐

  1. React——setState 同步异步问题

    2024-04-02 07:02:02       39 阅读
  2. ajax异步同步

    2024-04-02 07:02:02       42 阅读
  3. React setState同步异步

    2024-04-02 07:02:02       67 阅读
  4. react中的setState同步异步

    2024-04-02 07:02:02       57 阅读
  5. 【单元测试】测不测,这一个问题

    2024-04-02 07:02:02       50 阅读
  6. 同步同时同时

    2024-04-02 07:02:02       27 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-02 07:02:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-02 07:02:02       101 阅读
  3. 在Django里面运行非项目文件

    2024-04-02 07:02:02       82 阅读
  4. Python语言-面向对象

    2024-04-02 07:02:02       91 阅读

热门阅读

  1. 在Ubuntu 18.04上添加和删除用户的方法

    2024-04-02 07:02:02       33 阅读
  2. C#WPF设置圆角按钮样式

    2024-04-02 07:02:02       33 阅读
  3. ElasticSearch的DSL查询

    2024-04-02 07:02:02       39 阅读
  4. linxu tensorflow-1.13.1 C++动态库编译

    2024-04-02 07:02:02       33 阅读
  5. 介绍 TensorFlow 的基本概念和使用场景

    2024-04-02 07:02:02       29 阅读
  6. 【OpenCV-环境搭建】

    2024-04-02 07:02:02       37 阅读
  7. 【C/C++】C语言实现顺序表

    2024-04-02 07:02:02       31 阅读
  8. 手搓ajax的封装

    2024-04-02 07:02:02       38 阅读
  9. npm常用命令详解

    2024-04-02 07:02:02       38 阅读
  10. js怎样获取到时间戳?

    2024-04-02 07:02:02       34 阅读