Android React Native:setState in finally()
我在“render()”方法中使用以下代码启用/禁用网络活动指示器: 在“fetch()之前”和 在“.finally()”中,如下所示:Android React Native:setState in finally(),android,react-native,ecmascript-6,fetch-api,Android,React Native,Ecmascript 6,Fetch Api,我在“render()”方法中使用以下代码启用/禁用网络活动指示器: 在“fetch()之前”和 在“.finally()”中,如下所示: this.setState({networkActivity: true}); fetch(...) .then(...) .catch(...) .finally(this.setState({networkActivity: false})); this.setState({networkActivity: true}); const returnVa
this.setState({networkActivity: true});
fetch(...)
.then(...)
.catch(...)
.finally(this.setState({networkActivity: false}));
this.setState({networkActivity: true});
const returnValueOfSetState = this.setState({networkActivity: false});
fetch(...)
.then(...)
.catch(...)
.finally(returnValueOfSetState);
指示灯根本不显示。知道为什么吗
将“this.setState({networkActivity:false})”移动到“.then()”或“.catch()”块可以解决问题(作为解决方法)。指示灯亮了
在安卓6设备上测试。React本机版本:0.51由于fetch是一种web标准,因此它使用了大多数web浏览器可用的标准Promise API。这意味着“Finally”方法不存在 我相信这些都是可用的方法。您可以创建自己的Finally方法并将其作为Promise.resolve()调用,以完成承诺链 但是,如果该方法可用,则需要调用括号内的函数
// 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});
fetch(...)
.then(...)
.catch(...)
.finally(this.setState({networkActivity: false}));
this.setState({networkActivity: true});
const returnValueOfSetState = this.setState({networkActivity: false});
fetch(...)
.then(...)
.catch(...)
.finally(returnValueOfSetState);
这意味着您将networkActivity
设置为true
,然后立即将其设置回false
。然后当最终发生时
会尝试执行returnValueOfSetState
,我认为这是未定义的
,所以这是不可行的
这只是语法上的一个错误,您实际上想要的是:
this.setState({networkActivity: true});
fetch(...)
.then(...)
.catch(...)
.finally(() => {
this.setState({networkActivity: false});
});
React Native的fetch中不支持
finally
。但是核心团队计划很快改变fetchpolyfill(),这可能会解决这个问题
如果你想改变,这里是你可以做的
重写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);
});
});
};
const globalFetch=global.fetch;
global.fetch=(url:string,params:Object):Promise=>{
返回新承诺((解析:any=>void,拒绝:string=>void)=>{
StatusBar.SetNetworkActivityIndicator可视(true);
//TODO:使用Promise.finally,RN>=0.60
全局蚀刻(url,参数)
。然后((响应:任意)=>{
决心(回应);
StatusBar.SetNetworkActivityIndicator可视(false);
})
.catch((错误:任意)=>{
拒绝(错误);
StatusBar.SetNetworkActivityIndicator可视(false);
});
});
};
有趣的是,当我将它更改为时,最后(()=>this.setState({networkActivity:false}))
它就工作了!!迷茫…好发现!我更新了我的答案以反映您的评论。似乎“.finally()”现在在规范中,可能会成为标准的一部分,但另一方面,我的“巴贝尔”似乎已经理解了它。
this.setState({networkActivity: true});
fetch(...)
.then(...)
.catch(...)
.finally(() => {
this.setState({networkActivity: false});
});
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);
});
});
};