我在“render()”方法中使用以下代码启用/禁用网络活动指示器:
{this.state.networkActivity && <NetworkActivityIndicator/>}
现在当我放
this.setState({networkActivity: true});
在“fetch()”和之前
this.setState({networkActivity: false});
在“.finally()”中这样:
this.setState({networkActivity: true});
fetch(...)
.then(...)
.catch(...)
.finally(this.setState({networkActivity: false}));
指标根本没有显示。知道为什么吗?
将“this.setState({networkActivity:false})”移动到“.then()”或“.catch()”块可解决问题(作为解决方法)。指标出现。
在Android 6的设备上测试.React Native版本:0.51
由于fetch是Web标准,因此它使用大多数Web浏览器可用的标准Promise API。这意味着方法“Finally”不存在。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
Promise.all()
Promise.prototype.catch()
Promise.prototype.then()
Promise.race()
Promise.reject()
Promise.resolve()
我相信这些都是可用的方法。您可以创建自己的Finally方法并将其称为Promise.resolve()以完成您的Promise链。
但是,如果方法可用,则需要在括号内调用函数。
// incorrect -> ...finally(setState...)
// correct -> ...finally(function(){ this.setState() /* this might not be scoped properly here */ })
// correct -> ...finally(()=>this.setState())
finally
,像then
和catch
一样,在你的例子中,你提供this.setState()
的返回值给finally
。
两个setState
调用立即运行。
基本上你所拥有的代码大致在功能上是这样的:
this.setState({networkActivity: true});
const returnValueOfSetState = this.setState({networkActivity: false});
fetch(...)
.then(...)
.catch(...)
.finally(returnValueOfSetState);
这意味着您将networkActivity
设置为true
,然后立即将其设置回false
。然后,当finally
发生它试图执行returnValueOfSetState
,我相信是undefined
,所以这是一个无操作。
这只是语法错误,你真正想要的是:
this.setState({networkActivity: true});
fetch(...)
.then(...)
.catch(...)
.finally(() => {
this.setState({networkActivity: false});
});
React Native的fetch不支持finally
。但核心团队计划很快改变fetch polyfill(https://github.com/facebook/react-native/issues/23313),这可能会解决它。
如果你想改变StatusBar's network activity,这就是你能做的。
覆盖fetch
函数,注入网络活动加载器。
const globalFetch = global.fetch;
global.fetch = (url: string, params: Object): Promise<*> => {
return new Promise((resolve: any => void, reject: string => void) => {
StatusBar.setNetworkActivityIndicatorVisible(true);
// TODO: use Promise.finally with RN >= 0.60
globalFetch(url, params)
.then((response: any) => {
resolve(response);
StatusBar.setNetworkActivityIndicatorVisible(false);
})
.catch((error: any) => {
reject(error);
StatusBar.setNetworkActivityIndicatorVisible(false);
});
});
};