明白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文档所说:

“setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.”

所以当更新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 “晓得”什么时刻退出该事宜,什么时刻举行Batch Update道理能够参考这篇很简约易懂的文章

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()就会是同步的。

    原文作者:ericxuan
    原文地址: https://segmentfault.com/a/1190000018243060
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞