函数式组件中的useState

前言:众所周知useState是异步的,但网络上对于useState何时异步更新并没有一个共识,为了探究,做一个简单的实验,实验目的是探究useState与微任务、宏任务的先后关系

测试1

实验步骤:点击按钮触发事件,在事件中我们做三件事:修改state/定义一个宏任务setTimeout /定义一个微任务promise.then ,我们在微任务中打上debugger,暂停代码,观察此时页面是否更新了数据。

实验代码

import React, { useState } from 'react'
export default function Test() {
    const [msg, setMsg] = useState('我是初始值')
    const onChange = () => {
        setMsg('我是更新值')
        setTimeout(() => {
            console.log('宏任务')
        }, 0);
        Promise.resolve().then(res=>{            
            debugger  
            console.log('微任务')         
        })
    }
    return (
        <div>
            <h2>{msg}</h2>
            <button onClick={onChange}>按钮</button>
        </div>
    )
}

实验期望:

  • 如果页面更新了,则说明在微任务之前,useState就已经更新了状态,并且页面渲染完毕了
  • 如果页面未更新,则说明微任务在useState更新之前

实验结果

结果分析 结果符合第一种期望,useState在此微任务之前就完成了,由此得出useState异步更新是在微任务之前,同步代码之后的结果,这是不准确的。让我们进一步测试。

测试2

实验步骤:测试2在厕所1上调整下顺序。定义宏任务/定义微任务/修改state

实验代码:

import React, { useState } from 'react'
export default function Test() {
    const [msg, setMsg] = useState('我是初始值')
    const onChange = () => {
        setTimeout(() => {
            console.log('宏任务')
        }, 0);
        Promise.resolve().then(res=>{            
            debugger  
            console.log('微任务')         
        })
        setMsg('我是更新值')
    }
    return (
        <div>
            <h2>{msg}</h2>
            <button onClick={onChange}>按钮</button>
        </div>
    )
}

实验期望

  • 如果页面更新了,则说明在微任务之前,useState就已经更新了状态,并且页面渲染完毕了
  • 如果页面未更新,则说明微任务在useState更新之前

实验结果

结果分析

微任务已经执行了,但是页面还未更新,说明useState并不一定是在微任务之前执行。具体的执行结果与代码定义顺序有关。

类组件中的setState

setState在promise之前定义

export default class Test extends React.Component {
    state = {
        msg: '我是初始值'
    }
    handleClick = ()=>{
        setTimeout(() => {
           console.log('宏任务') 
        }, 0);
        this.setState({
            msg: '我是更新值'
        },()=>{
            console.log('更新了msg:', this.state.msg)
        })
        Promise.resolve().then(() => {
            console.log('微任务触发msg:', this.state.msg)
        })
    }
  render() {
    return (
      <div>
            <h2>{this.state.msg}</h2>
        <button onClick={this.handleClick}>按钮</button>
      </div>
    )
  }
}

执行结果:

结果说明:当先调用setState,后定义promise时,setState会在微任务之前更新状态。

setState在promise之后定义

export default class Test extends React.Component {
    state = {
        msg: '我是初始值'
    }
    handleClick = ()=>{
        setTimeout(() => {
           console.log('宏任务') 
        }, 0);
        Promise.resolve().then(() => {
            console.log('微任务触发msg:', this.state.msg)
        })
        this.setState({
            msg: '我是更新值'
        }, () => {
            console.log('更新了msg:', this.state.msg)
        })
    }
  render() {
    return (
      <div>
            <h2>{this.state.msg}</h2>
        <button onClick={this.handleClick}>按钮</button>
      </div>
    )
  }
}

实验结果:

结果说明:当先定义promise,后调用setState时,setState会在微任务之后更新状态。

结论

useState/setState的异步并不是一种在同步之后,微任务之前的特殊情况,而是一种和微任务相同的机制,看见简单理解为微任务,因为它的更新时机与微任务的调用相同,但react是不是用微任务来实现的更新,我不能确定。

以上就是React18 useState何时执行更新及微任务理解的详细内容,更多关于React18 useState执行更新的资料请关注Devmax其它相关文章!

React18 useState何时执行更新及微任务理解的更多相关文章

  1. react中useState使用:如何实现在当前表格直接更改数据

    这篇文章主要介绍了react中useState的使用:如何实现在当前表格直接更改数据,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  2. react纯函数组件setState更新页面不刷新的解决

    在开发过程中,经常遇到组件数据无法更新,本文主要介绍了react纯函数组件setState更新页面不刷新的解决,感兴趣的可以了解一下

  3. JavaScript事件循环剖析宏任务与微任务

    这篇文章主要为大家介绍了JavaScript事件循环剖析宏任务与微任务示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. react使用useState修改对象或者数组的值无法改变视图的问题

    这篇文章主要介绍了react使用useState修改对象或者数组的值无法改变视图的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  5. React18新增特性released的使用

    本文主要介绍了React18新增特性released的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  6. JavaScript中的useRef 和 useState介绍

    这篇文章主要给大家分享的是 JavaScript中的useRef 和 useState介绍,下列文章,我们将学习 useRef 和 useState hook是什么,它们的区别以及何时使用哪个。 这篇文章中的代码示例将仅涉及功能组件,但是大多数差异和用途涵盖了类和功能组件,需要的朋友可以参考一下

  7. React中hook函数与useState及useEffect的使用

    这篇文章主要介绍了React中hook函数与useState及useEffect的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

  8. vue中的任务队列和异步更新策略(任务队列,微任务,宏任务)

    这篇文章主要介绍了vue中的任务队列和异步更新策略(任务队列,微任务,宏任务),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  9. React中useState的使用方法及注意事项

    useState通过在函数组件里调用它来给组件添加一些内部state,下面这篇文章主要给大家介绍了关于React中useState的使用方法及注意事项的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

  10. React Hook中useState更新延迟问题及解决

    这篇文章主要介绍了React Hook中useState更新延迟问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部