美文网首页React.js学习
为什么React.setState是异步的?

为什么React.setState是异步的?

作者: 小进进不将就 | 来源:发表于2019-03-08 08:47 被阅读6次

(1)保证内部的一致性
目前 React 提供的 objects 有三种:① statepropsrefs
这三个 object 的行为和表现都是一致的,它们能够保证构建出协调的树(reconciled tree),这非常重要。

  • 举个例子:假设 state 是同步更新的
class Child extends React.Component{
  state={value:0,}
  this.setState({ value: this.state.value + 1 }) // 1 
  this.setState({ value: this.state.value + 1 }) // 2
}

如果父组件也需要该 statevalue 属性的话,就需要 状态提升:
父:

class Father extends React.Component{
  state={value:0,}
  Add(){
     this.setState({ value: this.state.value + 1 })
  } 
  render(){
    return (<Child add={this.Add.bind(this)}/>)
  }
}

子:

class Child extends React.Component{
  this.props.add()
}

注意:虽然在此假设中 state 是同步的,会立即更新,但是 props 却不会立即更新,而是 0

this.props.onIncrement() // 0
this.props.onIncrement() // 0

为啥?
因为 在没有重新渲染 父组件 的情况下,React 不会立即更新 props,如果 将 props 也设为同步更新的话,那么就必须放弃 批处理(batching)。
stateprops 变化一次,就重渲染一次,这会显著地降低 React 性能。

  • 还有个例子:
this.setState({this.state.value+this.props.value})

在此假设中 state 是立即更新的,但 props 不是,这就会导致 新的 state 的值不是期待的值。

综上:React 采用了 stateprops 采用 异步更新 的策略,保证内部一致性、保证状态提升更加安全。

(2)能够使用并发更新,从而优化性能
我们可能认为 状态更新是按照一定顺序更新的,但事实上,React 会根据不同的调用源,给不同的 setState() 分配不同的优先级。(妈的,我在上一篇文章还说 React 是顺序更新 state 的。。

调用源:事件处理、网络请求、动画 等。

  • 举个例子:
    用户正在一个聊天室和其他用户聊天,他向 input 框输入文字的时候,其他用户给他发送了一个 message。
    如果 state 是同步更新的,那是不是要立即重渲染 聊天室?
    肯定不行,这会严重影响用户体验。
    React 的做法是,将 message 的 setState 分配成低优先级,延迟 几毫秒去刷新。
    (只要我更新 message 的速度足够快,重渲染就跟不上我。。但不能保证任何时候都更新得足够快。)

React可能在 v17 的时候推出异步渲染 UI,这受益于 stateprops 的异步更新。

异步渲染 UI 有什么用?

  • 举个例子:
    当用户从 页面A 跳转到 页面B 的时候,通常会有一个 loading 页面的效果。

但是,如果网络请求非常快的话,loading 效果会闪烁一下,再呈现 页面B,这会影响用户体验。

如果 React 有了 异步渲染 UI 的功能,那么当你 setState() 的时候,React 会“偷偷地”渲染 页面B:
如果 渲染 页面B 花费的时间较长,那么开发者可以 加一个 loading 效果;
如果 渲染 页面B 花费的时间hin短,那么 React 偷偷渲染好 页面B 后,可以无缝切换到页面B。

同时,异步渲染 还能让用户在等待的过程中,继续和 旧页面 交互。

综上:如果 同步更新 state 的话,就无法在幕后渲染新页面,同时还保持旧页面的交互。

参考:https://github.com/facebook/react/issues/11527#issuecomment-360199710


(完)

相关文章

  • 为什么React.setState是异步的?

    (1)保证内部的一致性目前 React 提供的 objects 有三种:① state ② props ③ ref...

  • 实战:异步爬取之初识异步

    一、为什么要用异步? 许多之前没有听说过异步地朋友可能看到标题地第一反应就是:什么是异步?为什么要用异步? 我们先...

  • 异步基础

    异步 为什么要用异步方法? 为什么异步很难 怎么异步? 基于回调这是传统的异步模型,最常用的方法,早期版本的C# ...

  • JavaScript执行机制

    概述 为什么javascript是单线程的?为什么需要存在异步任务?JavaScript怎么处理异步任务的?宏任务...

  • vuex dispatch和commit 的区别

    dispatch:异步操作,commit :同步操作 为什么dispatch是异步而commit是同步呢? 首先,...

  • js 异步全览

    问题! JS 为什么是单线程的? 为什么需要异步? 单线程又是如何实现异步的呢? promise 的优点是什么? ...

  • react 常见setState的原理解析

    React.setState 首先引入一个栗子 4次log的值 分别为 0 0 2 3 setState 干了什么...

  • 为什么setState是异步的

    总结博文 github上面dan解释了为什么react setState为什么是异步的。 前提: 首先我们都应该同...

  • react 中的 promise详解

    一、promise是什么?为什么会有promise? 首先,promise是js的抽象异步处理对象实现异步编程的方...

  • 异步编程的前世今生

    异步编程的前世今生 1、为什么需要异步编程 异步编程是相对同步编程来说的,开发项目时,开发者总是希望,程序的执行顺...

网友评论

    本文标题:为什么React.setState是异步的?

    本文链接:https://www.haomeiwen.com/subject/nmfiuqtx.html