zoukankan      html  css  js  c++  java
  • React 的setState 异步理解

      create-react-app 创建项目,在App.js中创建Counter 组件

    import React from "react";
    
    export default class Counter extends React.Component {
    
        state = {
            counter: 0
        }
        handleClick = () => {
            this.setState({
                counter: this.state.counter + 1
            })
        }
        render() {
            return (
                <div>
                    <p>点击了{this.state.counter}次</p>
                    <button onClick={this.handleClick}>点击</button>
                </div>
            )
        }
    }

      这时,你想增加一个是否点击的状态hasButtonBeenClicked, 只要counter > 0 就算点击了,相当然的,在setState() 方法中,加了hasButtonBeenClicked 的更改

    this.setState({
          counter: this.state.counter + 1,
          hasButtonBeenClicked: this.state.counter > 0 });

      app.js 更改如下:

    export default class App extends React.Component {
    
        state = {
            counter: 0,
            hasButtonBeenClicked: false // 点击状态,默认是false
        }
        handleClick = () => {
            this.setState({
                counter: this.state.counter + 1,
                hasButtonBeenClicked: this.state.counter > 0  // 更改点击状态
            });
        }
        render() {
            return (
                <div>
                    <p>是否点击了{this.state.hasButtonBeenClicked.toString()}, 点击了{this.state.counter}次</p>
                    <button onClick={this.handleClick}>点击</button>
                </div>
            )
        }
    }

      你点击按钮一次,发现一个问题,是否点击显示false, 但确显示了点击了1次。

      

      这就是setState()的异步操作,一直知道setState()是异步改变状态,但没有这么写过,当调用setState 改变件的状态的时候,它并不会立即生效,React 为了提高效率,可能选择把几个状态的更改作为一组,一起改状态。也就是setState 中,如果我们更改的第二个或以后的状态,如果依赖第一个状态的改变,它有可能不生效。由于异步操作,第二个或以后的状态,不会取到最新的第一个状态的值。第二行中的hasButtonBeenClicked 中的this.state.counter 并不会获取到第一行中设置的最新状态,它仍然获取到的是this.state.counter 的旧值。

      如果,第二个状态依赖第一个状态,它就要用到setState 的第二个参数,回调函数,只有第一个状态set 成功之后,它才会执行这个回调, setState() 更改如下

    handleClick = () => {
            this.setState({ counter: this.state.counter + 1 }, 
                () => this.setState({ hasButtonBeenClicked: this.state.counter > 0 }));
        }

      第二个注意点,就是重复更改一个值。当使用seState()重复地修改一个状态的值的时候(handleClick的for循环),它并不会把所有的装态值都反应出来,而是取一个最近的值就完事了。

    handleClick = () => {
            for (let index = 0; index < 5; index++) {
                this.setState({ counter: this.state.counter + 1 });
            }
        }

      当点击按钮的时候,它显示的是1, 而不是5. 每点击一次,只加1. 这时要使用setState的第二种方式,setState的第一个参数,除了对象外,还可以接受一个函数(state, prop) 作为参数,要返回更新状态, 如下,这时你会发现显示5.

    handleClick = () => {
        for (let index = 0; index < 5; index++) {
            this.setState(state => ({
                counter: state.counter + 1
            }))
        }
    }
  • 相关阅读:
    Jmeter之检查点
    Jmeter之集合点
    Jmeter之参数化
    Jmeter组件认识
    Jmeter目录认识
    sts的web工程创建
    Jmeter的BeanShell脚本开发
    Jmeter插件开发
    Appium配置app老是反复安装问题的处理
    eclipse通过git代码的下载和上传
  • 原文地址:https://www.cnblogs.com/SamWeb/p/11305180.html
Copyright © 2011-2022 走看看