目录
抛出问题
setState的注意点
问题分析
同步更新(函数式setState)
同步异步setState的用法混合
首页 web前端 js教程 React中setState使用详解

React中setState使用详解

May 24, 2018 pm 02:19 PM
react setstate 详解

这次给大家带来React中setState使用详解,React中setState使用的注意事项有哪些,下面就是实战案例,一起来看一下。

抛出问题

class Example extends Component {
  contructor () {
    super()
    this.state = {
      value: 0,
      index: 0
    }
  }
  componentDidMount () {
    this.setState({value: this.state.value + 1})
    console.log(this.state.value) // 第一次输出
    this.setState({value: this.state.value + 1})
    console.log(this.state.value) // 第二次输出
    setTimeout(() => {
      this.setState({value: this.state.value + 1})
      console.log(this.state.value) // 第三次输出
      this.setState({value: this.state.value + 1})
      console.log(this.state.value) // 第四次输出
    }, 0);
        this.refs.button.addEventListener('click', this.click)
  }
  click = () => {
    this.setState({value: this.state.index + 1})
    this.setState({value: this.state.index + 1})
  }
  render () {
    return (
      <p><span>value: {this.state.value}index: {this.props.index}</span>
        <button ref="button" onClick={this.click}>点击</button>
      </p>
    )
  }
}
登录后复制
  • 这四次输出,按常理来说分别是: 1,2,3,4。但是,实际输出为: 0, 0, 2, 3

setState的注意点

  1. setState不会立刻改变React组件中state的值(即setState是异步更新)

  • setState通过一个队列机制实现state更新;

  • 当执行setState时,会将需要更新的state合并后放入状态队列,而不会立即更新,队列可以高效的批量更新state;

  • 通过this.state直接修改的值,state不会放入状态队列,当下次调用setState并对状态队列进行合并时,会忽略之前直接被修改的state.

  • setState通过引发一次组件的更新过程来引发重新绘制

    • 此处重绘指的就是引起React的更新生命周期函数4个函数:

    • shouldComponentUpdate(被调用时this.state没有更新;如果返回了false,生命周期被中断,虽然不调用之后的函数了,但是state仍然会被更新)

    • componentWillUpdate(被调用时this.state没有更新)

    • render(被调用时this.state得到更新)

    • componentDidUpdate

  • 多个相邻的state的修改可能会合并到一起一次执行

  •  this.setState({name: 'Pororo'})
     this.setState({age: 20})
    登录后复制
    • 等同于

     this.setState({name: 'Pororo',age: 20})
    登录后复制
    • 上面两块代码的效果是一样的。如果每次调用都引发一次生命周期更新,那性能就会消耗很大了。所以,React会将多个this.setState产生的修改放进一个队列里,等差不多的时候就会引发一次生命周期更新。

    问题分析

    • 对于前两次setState:

    this.setState({value: this.state.val + 1});
    console.log(this.state.value); // 第一次输出
    this.setState({value: this.state.val + 1});
    console.log(this.state.value); // 第二次输出
    登录后复制
    • 由于setState不会立即改变React组件中state的值,所以两次setState中this.state.value都是同一个值0,故而,这两次输出都是0。因而value只被加1。

    • 既然这样,那么是不是可以直接操作this.state呢?比如:this.state.value=this.state.value+1;

    • 这样的确可以修改this.state.value的状态但是却不可以引发重复渲染。

    • 所以,就必须通过React设定的setState函数去改变this.state,从而引发重新渲染。

    • setTimeout里面的两次setState:

    setTimeout(() => {
      this.setState({value: this.state.value + 1})
      console.log(this.state.value) // 第三次输出
      this.setState({value: this.state.value + 1})
      console.log(this.state.value) // 第四次输出
    }, 0);
    登录后复制
    • 这两次this.state的值同步更新了;

    • 同步更新:是由React引发的事件处理(比如:onClick引发的事件处理),调用setState会异步更新this.state;

    • 异步更新:除此之外的setState调用会同步执行this.setState。 “除此之外”指的是:绕过React通过addEventListener直接添加的事件处理函数和setTimeout/setInterval产生的异步调用。

    • this.setState更新机制图解:

    图片描述

    • 每次setState产生新的state会依次被存入一个队列,然后会根据isBathingUpdates变量判断是直接更新this.state还是放进dirtyComponent里回头再说。

    • isBatchingUpdates默认是false,也就表示setState会同步更新this.state。

    • 但是,当React在调用事件处理函数之前就会调用batchedUpdates,这个函数会把isBatchingUpdates修改为true,造成的后果就是由React控制的事件处理过程setState不会同步更新this.state。

    同步更新(函数式setState)

    1. 如果this.setState的参数不是一个对象而是一个函数时,这个函数会接收到两个参数,第一个是当前的state值,第二个是当前的props,这个函数应该返回一个对象,这个对象代表想要对this.state的更改;

    2. 换句话说,之前你想给this.setState传递什么对象参数,在这种函数里就返回什么对象。不过,计算这个对象的方法有些改变,不再依赖于this.state,而是依赖于输入参数state。

    function increment(state, props) {
      return {count: state.count + 1};
    }
    function incrementMultiple() {
      this.setState(increment);
      this.setState(increment);
      this.setState(increment);
    }
    登录后复制
    • 假如当前this.state.count的值是0,第一次调用this.setState(increment),传给increment的state参数是0,第二调用时,state参数是1,第三次调用是,参数是2,最终incrementMultiple让this.state.count变成了3。

    • 对于多次调用函数式setState的情况,React会保证调用每次increment时,state都已经合并了之前的状态修改结果。

    要注意的是,在increment函数被调用时,this.state并没有被改变,依然,要等到render函数被重新执行时(或者shouldComponentUpdate函数返回false之后)才被改变。

    同步异步setState的用法混合

    function incrementMultiple() {
      this.setState(increment);
      this.setState(increment);
      this.setState({count: this.state.count + 1});
      this.setState(increment);
    }
    登录后复制
    • 在几个函数式setState调用中插入一个传统式setState调用,最后得到的结果是让this.state.count增加了2,而不是增加4。

    • 这是因为React会依次合并所有setState产生的效果,虽然前两个函数式setState调用产生的效果是count加2,但是中间出现一个传统式setState调用,一下子强行把积攒的效果清空,用count加1取代。

    • 所以,传统式setState与函数式setState一定不要混用。

    相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

    推荐阅读:

    JS中使用接口步骤详解

    EasyCanvas绘图库在Pixeler项目开发中使用实战总结

    以上是React中setState使用详解的详细内容。更多信息请关注PHP中文网其他相关文章!

    本站声明
    本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

    热AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智能驱动的应用程序,用于创建逼真的裸体照片

    AI Clothes Remover

    AI Clothes Remover

    用于从照片中去除衣服的在线人工智能工具。

    Undress AI Tool

    Undress AI Tool

    免费脱衣服图片

    Clothoff.io

    Clothoff.io

    AI脱衣机

    AI Hentai Generator

    AI Hentai Generator

    免费生成ai无尽的。

    热门文章

    R.E.P.O.能量晶体解释及其做什么(黄色晶体)
    1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.最佳图形设置
    1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
    威尔R.E.P.O.有交叉游戏吗?
    1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

    热工具

    记事本++7.3.1

    记事本++7.3.1

    好用且免费的代码编辑器

    SublimeText3汉化版

    SublimeText3汉化版

    中文版,非常好用

    禅工作室 13.0.1

    禅工作室 13.0.1

    功能强大的PHP集成开发环境

    Dreamweaver CS6

    Dreamweaver CS6

    视觉化网页开发工具

    SublimeText3 Mac版

    SublimeText3 Mac版

    神级代码编辑软件(SublimeText3)

    Win11管理员权限获取详解 Win11管理员权限获取详解 Mar 08, 2024 pm 03:06 PM

    Windows操作系统是全球最流行的操作系统之一,其新版本Win11备受瞩目。在Win11系统中,管理员权限的获取是一个重要的操作,管理员权限可以让用户对系统进行更多的操作和设置。本文将详细介绍在Win11系统中如何获取管理员权限,以及如何有效地管理权限。在Win11系统中,管理员权限分为本地管理员和域管理员两种。本地管理员是指具有对本地计算机的完全管理权限

    Oracle SQL中的除法运算详解 Oracle SQL中的除法运算详解 Mar 10, 2024 am 09:51 AM

    OracleSQL中的除法运算详解在OracleSQL中,除法运算是一种常见且重要的数学运算操作,用于计算两个数相除的结果。除法在数据库查询中经常用到,因此了解OracleSQL中的除法运算及其用法是数据库开发人员必备的技能之一。本文将详细讨论OracleSQL中除法运算的相关知识,并提供具体的代码示例供读者参考。一、OracleSQL中的除法运算

    PHP模运算符的作用及用法详解 PHP模运算符的作用及用法详解 Mar 19, 2024 pm 04:33 PM

    PHP中的模运算符(%)是用来获取两个数值相除的余数的。在本文中,我们将详细讨论模运算符的作用及用法,并提供具体的代码示例来帮助读者更好地理解。1.模运算符的作用在数学中,当我们将一个整数除以另一个整数时,会得到一个商和一个余数。例如,当我们将10除以3时,商为3,余数为1。模运算符就是用来获取这个余数的。2.模运算符的用法在PHP中,使用%符号来表示模

    PHP、Vue和React:如何选择最适合的前端框架? PHP、Vue和React:如何选择最适合的前端框架? Mar 15, 2024 pm 05:48 PM

    PHP、Vue和React:如何选择最适合的前端框架?随着互联网技术的不断发展,前端框架在Web开发中起着至关重要的作用。PHP、Vue和React作为三种具有代表性的前端框架,每一种都具有其独特的特点和优势。在选择使用哪种前端框架时,开发人员需要根据项目需求、团队技能和个人偏好做出明智的决策。本文将通过比较PHP、Vue和React这三种前端框架的特点和使

    linux系统调用system()函数详解 linux系统调用system()函数详解 Feb 22, 2024 pm 08:21 PM

    Linux系统调用system()函数详解系统调用是Linux操作系统中非常重要的一部分,它提供了一种与系统内核进行交互的方式。其中,system()函数是一个常用的系统调用函数之一。本文将详细介绍system()函数的使用方法,并提供相应的代码示例。系统调用的基本概念系统调用是用户程序与操作系统内核交互的一种方式。用户程序通过调用系统调用函数来请求操作系统

    Java框架与前端React框架的整合 Java框架与前端React框架的整合 Jun 01, 2024 pm 03:16 PM

    Java框架与React框架的整合:步骤:设置后端Java框架。创建项目结构。配置构建工具。创建React应用。编写RESTAPI端点。配置通信机制。实战案例(SpringBoot+React):Java代码:定义RESTfulAPI控制器。React代码:获取并显示API返回的数据。

    Linux的curl命令详解 Linux的curl命令详解 Feb 21, 2024 pm 10:33 PM

    Linux的curl命令详解摘要:curl是一种强大的命令行工具,用于与服务器进行数据通信。本文将介绍curl命令的基本用法,并提供实际的代码示例,帮助读者更好地理解和应用该命令。一、curl是什么?curl是一个命令行工具,用于发送和接收各种网络请求。它支持多种协议,如HTTP、FTP、TELNET等,并提供了丰富的功能,如文件上传、文件下载、数据传输、代

    详细解析C语言学习路线 详细解析C语言学习路线 Feb 18, 2024 am 10:38 AM

    C语言作为一门广泛应用在软件开发领域的编程语言,是很多程序员初学者的首选。学习C语言不仅可以帮助我们建立编程的基础知识,还可以提升我们解决问题和思考的能力。本文将详细介绍一条C语言学习的路线图,帮助初学者更好地规划自己的学习进程。1.学习基本语法在开始学习C语言之前,我们首先需要了解C语言的基本语法规则。这包括变量和数据类型、运算符、控制语句(如if语句、

    See all articles