学过React,setState的宝宝们,都知道为了提高性能React将setState设置为批次更新,即异步操作函数,不能以顺序控制流的方式设置某些事件,不能依赖于this.state计算未来状态,比如,我们希望拿到服务端来的数据后,再进行其他操作,在大型应用中,如果事件的触发速度快于setState的更新速度,那么计算的值完全就是错的,那么怎么解决这个问题呢?
完成回调
在setState函数的第二个参数允许传入回调函数,在状态更新完毕后进行调用
this.setState({
load: !this.state.load,
count: this.state.count + 1
}, () => {
console.log(this.state.count);
console.log('
加载完成
')
});
Promise来封装setState
setStateAsync(state) {
return new Promise((resolve) => {
this.setState(state, resolve)
});
}
setStateAsync 返回的是Promise对象,所以在调用时可以用es的Async/Await语法来优化
async componentDidMount() {
StatusBar.setNetworkActivityIndicatorVisible(true)
const res = await fetch('https://api.ipify.org?format=json')
const {ip} = await res.json()
await this.setStateAsync({ipAddress: ip})
StatusBar.setNetworkActivityIndicatorVisible(false)
}
这里我们就可以保证在setState渲染完毕之后调用外部状态栏将网络请求状态修改为已结束,整个组件的完整定义为:
class Exampleextends Component {
state = {}
setStateAsync(state) {
...
}
async componentDidMount() {
...
}
传入状态计算函数
除了使用回调函数的方式监听状态更新结果之外,React还允许我们传入某个状态计算函数而不是对象来作为第一个参数。状态计算函数能够为我们提供可信赖的组件的State与Props值,即会自动地将我们的状态更新操作添加到队列中并等待前面的更新完毕后传入最新的状态值:
this.setState(function(prevState, props){
return {showForm: !prevState.showForm}
});
incrementCount(){
this.setState((prevState, props) => ({
count: prevState.count + 1
}));
this.setState((prevState, props) => ({
count: prevState.count + 1
}));
}
这里的第二个setState传入的prevState值就是第一个setState执行完毕之后的计数值,也顺利保证了连续自增两次
至此已经结束,希望对于各位可以有帮助