setState 是微任务还是宏任务?

588 阅读1分钟
  1. 在 setTimeout 或 自定义DOM事件中setState是同步执行的
  2. 其余情况,在 react 内部事件中, setState是 “异步” 执行的
  • setState本质是同步,不过让react做成了异步的样子
  • 因为要考虑性能,多次修改setState,只进行一次 DOM 渲染。
  • 说setState是 “异步” 执行的,是不严谨的

在 react 内部事件中,先处理完内部事件及 setState 的合并,再处理 setState 的回调。所以会先于微任务执行。

react 中的事件 是合成事件,分为 前置事件处理和后置事件处理, setState 的回调就属于后置事件处理。

答案

setState 是同步执行,state 都是同步更新。即,在微任务 Promise.then 开始之前,state 已经计算完了。

同步,既不是微任务或宏任务。

代码:

import React from 'react'

class Example extends React.Component {
    constructor() {
      super()
      this.state = {
        val: 0
      }
    }

    clickHandler = () => {
      console.log('--- start ---')

      Promise.resolve().then(() => console.log('promise then') /* callback */)

      // “异步”
      this.setState(
        { val: this.state.val + 1 },
        () => { console.log('state...', this.state) } // callback
      )

      console.log('--- end ---')
    }

    componentDidMount() {
      // setTimeout(() => {
      //   console.log('--- start ---')

      //   Promise.resolve().then(() => console.log('promise then'))

      //   this.setState(
      //     { val: this.state.val + 1 }
      //   )
      //   console.log('state...', this.state)
    
      //   console.log('--- end ---')
      // })
    }
  
    render() {
      return <p id="p1" onClick={this.clickHandler}>
        setState demo: {this.state.val}
      </p>
    }
}

export default Example