您好,欢迎来到微智科技网。
搜索
您的当前位置:首页理解setState(),异步还是同步?

理解setState(),异步还是同步?

来源:微智科技网

state

state的存在是为了动态改变组件,比如根据不同的用户操作和网络请求,来重新渲染组件。

setState()是React给我们的一个API,用来改变或定义state。

setState()的批量操作(batching)

在一个事件handler函数中,不管setState()被调用多少次,他们也会在函数执行结束以后,被归结为一次重新渲染, 可以优化性能, 这个等到最后一起执行的行为被称为batching

所以在函数内的setState()是有序的,如果要更改同一个state key,最后被调用的总会覆盖之前的。

因为batching的存在,所以这样的代码会和期待有出入。

//假设现在this.state.value = 0;

function eventHandler(){
    this.setState({value:this.state.value + 1});
    this.setState({value:this.state.value + 1});
    this.setState({value:this.state.value + 1});
}

//最后this.state.value仍然会是1,不是3;

所以不能依赖this.state来计算未来状态。如果想实现这样的效果,应该传一个函数给setState。这个函数有两个参数,第一个为previous state,第二个为props。这里的例子和props无关,只需要第一个参数,所以要达到效果,代码是这样

// 假设 this.state = { value: 0 };

function eventHandler(){
    this.setState((state) => ({ value: state.value + 1}));
    this.setState((state) => ({ value: state.value + 1}));
    this.setState((state) => ({ value: state.value + 1}));
}

//现在this.state.value === 3;

到这里我们得到结论,setState是异步执行的。

如React文档所说:

所以当更新state,然后想打印state的时候,应该使用回调。

this.setState({key: val},()=>console.log(this.state));    

所以setState总是异步的,吗?

当setState()不在事件Handler函数中,如在使用ajax的时候,这种batching的异步表现又不会发生


promise.then(() => {
  // 不在事件函数中,所以setState立刻执行
  this.setState({a: true}); // 重新渲染 {a: true, b: false }
  this.setState({b: true}); // 重新渲染 {a: true, b: true }
});

同步异步要分情况来看:

1. React事件函数使用,像这样用最常用的形式绑定函数
constructor(props){
    ...
    this.onClick = this.onClick.bind(this);
}

onClick(){
    this.setState({key:val});
}

render(){
    return(
        <div>
            <button onClick = {this.onClick}>Click me</button>
        </div>
}

这里batching发生,异步表现,是因为这种常规情景下React “知道”什么时候退出该事件,什么时候进行。原理可以参考这篇很简洁易懂的文章

2.其他情景,如上面的ajax情景,或这样用addEventListener绑定函数
componentDidMount(){
    document.querySelector('#btn').addEventListener('click,this.onClick);
}
    
    render(){
        return(
            <div>
                <button id="btn">Click me</button>
            </div>
    }
}

脱离了React的控制,React不知道如何进行Batch Update,setState()就会是同步的。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 7swz.com 版权所有 赣ICP备2024042798号-8

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务