前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React 的 setState 同步还是异步

React 的 setState 同步还是异步

作者头像
前端西瓜哥
发布2022-12-21 20:00:59
7010
发布2022-12-21 20:00:59
举报
文章被收录于专栏:前端西瓜哥的前端文章

大家好,我是前端西瓜哥。今天来聊聊 React 的 setState 是同步还是异步的。

Sync Mode

其实 React 官方叫 Legacy Mode(Legacy 表示过时的),但为了更好地表示这种模型的特性,我还是将它叫做 Sync(同步) Mode。

Sync Mode 是旧的同步不可中断的架构。使用 ReactDom.render 方法开启:

代码语言:javascript
复制
import ReactDOM from "react-dom";
import App from "./App";

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

这种模式的特定是 同步执行

分为两种情况讨论:

  1. React 的流程中的 setState,我们。比如生命周期函数、React 的事件响应函数;
  2. 游离在 React 控制之外的 setState。比如定时器的触发、DOM 原生事件;

如果在 React 流程中,setState 是批量延后执行的

例子:

代码语言:javascript
复制
componentDidMount() {
  console.log("setState 前:", this.state.count);

  this.setState({
    count: this.state.count + 1
  });

  console.log("setState 后:", this.state.count);
}

输出结果为:

代码语言:javascript
复制
setState 前:0
setState 后:0

可以看到 setState 并不是立即生效的,所以我们可以将其认为是异步的吗?然鹅并不是。

其实在这种情况下 React 是将 setState 要做的各种更新,先不立即更新,而是先保存起来,在声明周期函数的后期阶段才将这些更新的内容做一个合并,合并成一个对象,然后再去更新,是一种批量延后的行为。

它还是同步的,但是延后的同步。

如果在 React 流程外,setState 是立即同步更新

例子:

代码语言:javascript
复制
componentDidMount() {
  setTimeout(() => {
    console.log("setState 前:", this.state.count);

    this.setState({
      count: this.state.count + 1
    });

    console.log("setState 后:", this.state.count);
  });
}

输出结果为:

代码语言:javascript
复制
setState 前:0
setState 后:1

这里用 setTimeout 是脱离 React 流程的,此时 setState 会做同步更新,立即更新状态。

如果你希望在 React 流程外也做批量更新,可以用 React.unstable_batchedUpdates 进行包裹,效果类似在 React 流程中,会延迟同步执行。

Concurrent Mode

Concurrent Mode,并发模式。所谓并发,就是将 render 操作对应的大任务,拆分成一个个小任务,去异步执行,和其他任务表现为并发执行。

并发的意思,是在单线程的 JavaScript 中,将原本需要依次执行的多个任务,每个都拆分,每次只执行一小部分,看起来好像所有任务都在同时执行的感觉。

需要注意的是,并发并不是并行,并发只是因为速度很快,看起来像是同时进行而已。并行则是真正的有物理上的分身,真正的多个线程一起干活。

使用 createRoot 方式启用:

代码语言:javascript
复制
import ReactDOM from "react-dom";
import { createRoot } from "react-dom/client";

import App from "./App";

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(<App />);

对于上面两种写法下,控制台输出都是:

代码语言:javascript
复制
setState 前:0
setState 后:0

在 React 流程中,setState 是并发的,即异步可中断

setState 后不会立即更新,不能立刻得到 state 的改变。

结尾

总结一下,同步模式(sync)下,React 流程中的 setState 更新操作是批量延迟同步的,流程外的 setState 是立即同步执行的。

使用并发模式(concurrent)下,使用了全新的 Fiber 架构,setState 的更新是异步的。

我是前端西瓜哥,欢迎关注我,学习更多前端知识。


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-11-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端西瓜哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Sync Mode
  • Concurrent Mode
  • 结尾
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档