react setState

简介: react setState

setState异步、同步、宏任务、微任务?

1、在react生命周期里,当执行setState时,setState会放入队列。

代码执行后,从表面看形成了异步,但不是异步,代码执行还是同步的。

handleClick = () => {
   
  console.log('1')
  this.setState({
   
    count: 2
  }, () => {
   
    console.log('2')
  })
  console.log('3')
}
// 1,3,2

setState 看着像是一个异步的操作。

原因,在 React 的生命周期以及绑定的事件流中,所有的 setState 会优先缓存到一个队列中,在整个事件结束后或者 mount 流程结束后,会取出之前缓存的 setState 队列进行一次执行,触发 state 更新。

2、如果我们执行跳出 React 的事件流或者生命周期,就能打破 React 对 setState 的掌控。

最简单的方法,就是把 setState 放到 setTimeout 中。

handleClick = () => {
   
   setTimeout(() => {
   
      console.log('1')
      this.setState({
   
        count: 2
      }, () => {
   
        console.log('2')
      })
      console.log('3')
   })
}
// 1,2,3

一、Arguments

1、arguments[0]

(1)对象

handle() {
   
  this.setState({
    count: 1 })
}

(2)函数

handle() {
   
  this.setState((prevState) => ({
    count: prevState.count + 1 }))
}

在setState中的第1个参数,可以传对象或函数

2、arguments[1]

handle() {
    this.setState({ count: 1 }, () => {
        console.log(this.state)
    })
}

在setState中的第2个参数,是回调函数。因为setState()是异步执行,故可以通过第2个参数中的回调函数执行同步操作。

二、异步与同步

1、多个setState()的执行

handle() {
  // 初始化 `count` 为 0
  console.log(this.state.count) // -> 0
  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) // -> 0
}

初始count与执行完setState()后的count都是0,这是因为 setState 是异步执行。

如何解决:

handle() {
  this.setState((prevState) => ({ count: prevState.count + 1 }))
  this.setState((prevState) => ({ count: prevState.count + 1 }))
  this.setState((prevState) => ({ count: prevState.count + 1 }))
}
// 或者使用async / await

当this.setState()被调用的时候,React会重新调用render方法来重新渲染UI。

如果每次执行调用就去进行重新渲染,会损耗性能。批量更新,可以避免短期内的多次渲染,变成一次性更新。

所以setState就相当于是一个异步操作,不能立即被修改。state的值在修改了之后并不会立即被修改,而是也有一个类似的队列,setState通过一个队列机制实现state的更新。

当执行setState时,会把需要更新的state合并后放入状态队列,而不会立刻更新this.state,利用这个队列机制可以高效的批量的更新state。

2、setState的执行步骤

(1)当调用setState时,实际上会执行enqueueSetState方法,并对partialState以及_pendingStateQueue更新队列进行合并,最终通过enqueueUpdate执行state更新。

performUpdateIfNecessary方法获取_pendingElement、_pendingStateQueue、_pendingForceUpdate,并调用reciveComponent和updateComponent方法进行组件更新。

(2) 如果组件当前正处于update事务中,则先将Component存入dirtyComponent中。否则调用batchedUpdates处理。

(3)batchedUpdates发起一次transaction.perform()事务。

开始执行事务初始化、运行、结束三个阶段:

初始化:事务初始化阶段没有注册方法,故无方法要执行

运行:执行setSate时传入的callback方法,一般不会传callback参数

结束:更新isBatchingUpdates为false,并执行FLUSH_BATCHED_UPDATES这个wrapper中的close方法

(4)FLUSH_BATCHED_UPDATES在close阶段,会循环遍历所有的dirtyComponents,调用updateComponent刷新组件,并执行它的pendingCallbacks, 也就是setState中设置的callback。

目录
相关文章
|
6月前
|
前端开发 JavaScript
React 中 setState 什么时候是同步的,什么时候是异步的
React 中 setState 什么时候是同步的,什么时候是异步的
61 0
|
8月前
|
前端开发 JavaScript
react的setState是异步还是同步
react的setState是异步还是同步
|
4月前
|
前端开发
说说React中setState和replaceState的区别?
在 React 中,setState()和 replaceState()是用于更新组件状态的两个方法。它们之间有一些区别
20 0
|
4月前
|
前端开发 算法
React中的setState执行机制?
React中的setState执行机制?
|
4月前
|
前端开发
React中setState方法详细讲解
React中setState方法详细讲解
|
5月前
|
前端开发 JavaScript 算法
react中的setState的执行机制
react中的setState的执行机制
22 0
|
1月前
|
前端开发
【React学习】—SetState的使用(九)
【React学习】—SetState的使用(九)
|
6月前
|
前端开发 JavaScript 数据管理
react数据管理之setState与Props
react数据管理之setState与Props
46 0
|
7月前
|
前端开发
React-组件-setState
React-组件-setState
24 0
|
9月前
|
前端开发 JavaScript
React中的setState的执行机制
React中的setState的执行机制
76 0