由于react中把setState设置为异步操作函数,这有时候会给我们带来以一些问题,下面介绍一下怎么解决这个问题。
1. 在setState完成的回调里执行需要的操作
setState函数的第二个参数允许传入回调函数,在状态更新完毕后进行调用,譬如:
this.setState({
load: !this.state.load,
count: this.state.count + 1
}, () => {
console.log(this.state.count);
console.log('加载完成')
});
2. 传入状态计算函数
除了使用回调韩式的方式监听状态更新结果之外,react还允许我们传入某个状态计算函数而不是对象作为第一个参数。状态计算函数能够为我们提供可依赖的组件的state与props值,即会自动的将我们的状态更新操作添加到队列中并等待前面的更新完毕后传入更新的状态值:
this.setState(function(prevState, props){
return {需要改变的state的名称: 改变之后的state的值}
});
这里我们以简单的计数器为例,我们希望用户点击按钮之后将计数值连加两次,
直观的写法我们可以连续调用两次setState函数,这边的用法可能看起来有点怪异,不过更多的是为了说明异步更新带来的数据不可预测问题。
incrementCount(){
this.setState({count : this.state.count + 1})
this.setState({count : this.state.count + 1})
}
上述代码的效果是每次点击之后计数值只会加1,实际上第二个setState并没有等待第一个setState执行完毕就开始执行了,因此其依赖的当前计数值完全是错的。我们当然可以使用上文提及的setStateAsync来进行同步控制,不过这里我们使用状态计算函数来保证同步性:
incrementCount(){
this.setState((prevState, props) => ({
count: prevState.count + 1
}));
this.setState((prevState, props) => ({
count: prevState.count + 1
}));
}
这里的第二个setState传入的prevState值就是第一个setState执行完毕之后的计数值,也顺利保证了连续自增两次。