ReactNative的视图刷新机制和React一脉相承,ReactNative通过this.state来访问state,通过this.setState()方法来更新state。当this.setState()方法被调用的时候,ReactNative会重新调用render方法来重新渲染UI。
同步更新可能会失败
这段时间在做项目的时候发现了通过this.setState()更新state延迟的问题,就是当state的值还没更新完毕的时候,这时render方法已经渲染完毕,通过this.state计算的UI状态就会出现错误,特别是当你的视图层级结构非常深的时候这种情况更明显。举个例子,我们希望在从服务端抓取数据并且渲染到界面之后,再隐藏加载进度条或者外部加载提示。
componentDidMount() {
fetch('https://test.com')
.then((res) => res.json())
.then(
(data) => {
this.setState({ data:data });
StatusBar.setNetworkActivityIndicatorVisible(false);
}
);
}
因为 setState 函数并不会阻塞等待状态更新完毕,因此 setNetworkActivityIndicatorVisible 有可能先于数据渲染完毕就执行。
解决方案
我们来看一下React文档中对setState的说明
void setState(
function|object nextState,
[function callback]
)
The second (optional) parameter is a callback function that will be executed once setState is completed and the component is re-rendered.
翻译一下,第二个参数是一个回调函数,在setState的异步操作结束并且组件已经重新渲染的时候执行。也就是说,我们可以通过这个回调来拿到更新的state的值。
所以上面的代码我们可以这样写,可以实现同步更新。
componentDidMount() {
fetch('https://test.com')
.then((res) => res.json())
.then(
(data) => {
this.setState({ data:data },()=>{
StatusBar.setNetworkActivityIndicatorVisible(false);
});
}
);
}