当前位置:   article > 正文

React:setState同步or异步?_react setstate同步和异步

react setstate同步和异步

引言


setState是‘最熟悉的陌生人’,当你入门React的时候,接触的第一波API里一定有setState-----数据驱动视图。当你项目的数据流乱作一团的时候,始作俑者也往往是setState----工作机制太复杂,文档又不说清楚。

setState 的工作机制渐渐与 React 调和算法并驾齐驱,成了 React 核心原理中区分度最高的知识模块之一。

“神奇时刻”到底何时发生?
state到底是在哪个环节发生了变化呢?
所谓的“恰恰好”又如何界定呢?

关于setState的问题,由下面一段代码说起:

给出一个这样的 App 组件,在它的内部会有如下代码所示的几个不同的 setState 操作:

  1. import React, { Component } from 'react';
  2. export default class App extends Component {
  3. state = {
  4. count: 0
  5. };
  6. handleIncrement = () => {
  7. console.log('increment setState前的count', this.state.count);
  8. this.setState({
  9. count: this.state.count + 1
  10. });
  11. console.log('increment setState后的count', this.state.count);
  12. };
  13. handleTriple = () => {
  14. console.log('triple setState前的count', this.state.count);
  15. this.setState({
  16. count: this.state.count + 1
  17. });
  18. this.setState({
  19. count: this.state.count + 1
  20. });
  21. this.setState({
  22. count: this.state.count + 1
  23. });
  24. console.log('triple setState后的count', this.state.count);
  25. };
  26. handleReduce = () => {
  27. setTimeout(() => {
  28. console.log('reduce setState前的count', this.state.count);
  29. this.setState({
  30. count: this.state.count - 1
  31. });
  32. console.log('reduce setState后的count', this.state.count);
  33. }, 0);
  34. };
  35. render() {
  36. return (
  37. <div>
  38. <div>{this.state.count}</div>
  39. <button onClick={this.handleIncrement}>点我增加</button>
  40. <button onClick={this.handleTriple}>点我增加三倍</button>
  41. <button onClick={this.handleReduce}>点我减少</button>
  42. </div>
  43. );
  44. }
  45. }

此时有个问题,若从左到右依次点击每个按钮,控制台的输出会是什么样的?

  如果你是一个熟手 React 开发,那么 handleIncrement这个方法的输出结果想必难不倒你——正如许许多多的 React 入门教学所声称的那样,“setState是一个异步的方法”,这意味着当我们执行完 setState 后,state本身并不会立刻发生改变。 因此紧跟在 setState后面输出的 state值,仍然会维持在它的初始状态(0)。在同步代码执行完毕后的某个“神奇时刻”,state才会“恰恰好”地增加到 1。

  但这个“神奇时刻”到底何时发生,所谓的“恰恰好”又如何界定呢?如果你对这个问题搞不太清楚,那么 triple方法的输出对你来说就会有一定的迷惑性——setState一次不好使, setState三次也没用,state 到底是在哪个环节发生了变化呢?

  带着这样的困惑,你决定先抛开一切去看看 handleReduce方法里是什么光景,结果更令人大跌眼镜,reduce 方法里的 setState竟然是同步更新的!这…到底是我们初学 React时拿到了错误的基础教程,还是电脑坏了?
 

异步的动机和原理——批量更新的艺术

  在setState 调用之后,都发生了哪些事情?基于截止到现在的专栏知识储备,可能会更倾向于站在生命周期的角度去思考这个问题,得出一个如下图所示的结论:

 从图上我们可以看出,一个完整的更新流程,涉及了包括 re-render(重渲染) 在内的多个步骤。re-render本身涉及对 DOM 的操作,它会带来较大的性能开销。假如说“一次 setState就触发一个完整的更新流程”这个结论成立,那么每一次 setState的调用都会触发一次 re-render,我们的视图很可能没刷新几次就卡死了。这个过程如我们下面代码中的箭头流程图所示:

th
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/383465
推荐阅读
相关标签
  

闽ICP备14008679号