2-9 认识setState

setState,它对状态的改变,可能是异步的

如果改变状态的代码处于某个HTML元素的事件中,则其是异步的,否则是同步

最佳实践:
1.把所有的setState当做是异步的
2.永远不要信任setState调用之后的状态
3.如果需要使用改变之后的状态,需要使用回调函数(setState的第二个参数)

import React, { Component } from 'react'

export default class Comp extends Component {

    state = {
        n: 0
    }
    handleClick = () => {
        this.setState({
            n: this.state.n + 1
        }, () => {
            //状态完成改变之后触发,该回调运行在render之后
            //可以拿到改变之后的值
            console.log(this.state.n);
        });
    }

    render() {
        console.log("render");
        return (
            <div>
                <h1>
                    {this.state.n}
                </h1>
                <p>
                    <button onClick={this.handleClick}>+</button>
                </p>
            </div>
        )
    }
}

4.如果新的状态要根据之前的状态进行运算,使用函数的方式改变状态(setState的第一个参数)

import React, { Component } from 'react'
export default class Comp extends Component {
    state = {
        n: 0
    }
    handleClick = () => {
        this.setState(cur => {
            //参数cur表示当前的状态
            //该函数的返回结果,会混合(覆盖)掉之前的状态
            //该函数是异步执行
            return {
                n: cur.n + 1
            }
        }, ()=>{
            //所有状态全部更新完成,并且重新渲染后执行
            console.log("state更新完成", this.state.n);
        });
    }

    render() {
        console.log("render");
        return (
            <div>
                <h1>
                    {this.state.n}
                </h1>
                <p>
                    <button onClick={this.handleClick}>+</button>
                </p>
            </div>
        )
    }
}

5.React会对异步的setState进行优化,将多次的setState进行合并(将多次的状态改变完成后,再统一对state进行改变,然后触发render)
多次触发:使用setState第一个函数

      this.setState(cur => ({
            n: cur.n + 1
        }));

        this.setState(cur => ({
            n: cur.n + 1
        }));
         this.setState(cur => ({
            n: cur.n + 1
        }));

到底是同步还是异步?

  1. setState只在合成事件和钩子函数中是"异步"的,在原生事件和setTimeout中是同步的

  2. setState的"异步"并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形成了所谓的"异步",当然可以通过第二个参数setState(partialState,callback)中callback拿到更新后的结果。 partialState–>局部状态

  3. setState的批量更新优化也是建立在"异步"(合成事件、钩子函数)之上的,在原生事件和setTimeout中不会批量更新,在"异步"中如果对同一个值进行多次setState,setState的批量更新策略会对其进行覆盖,取最后一次的执行,如果是同时setState多个不同的值,在更新是会对其进行合并批量更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值