我正在开发一个从外部API中获取数据的应用程序。每当用户尝试建立连接但没有连接时,他们就会收到丑陋的红色死亡屏幕。
我一直在玩NetInfo
来缓解这个问题,特别是NetInfo.isConnected
。
我的render
逻辑结构的方式,我认为我不能让this.state.isConnected === false
实际触发 - 即使我故意在iOS模拟器中断开互联网连接。如果我设置此逻辑以在AlertIOS.Alert
返回任何虚假值时触发其this.state.isConnected
方法,即使用户有连接,它也会触发该令人不愉快的警报,因为getInitialState
最初将其设为null
。我该怎么办呢?
此外,我是否应该为所有组件重新创建此逻辑,因为我有一种感觉,我需要几乎不断检查网络访问?
===
这是我的getInitialState
生命周期方法
getInitialState: function() {
return {
accessToken: false,
isConnected: null,
selectedTab: 'products'
}
},
然后在componentWillMount
中,我为NetInfo.isConnected
设置了一个事件监听器,并手动获取我的连接状态:
componentWillMount: function() {
NetInfo.isConnected.addEventListener('change', this.handleConnectivityChange)
NetInfo.isConnected.fetch().done((data) => {
console.log(this.state.isConnected);
this.setState({
isConnected: data
})
})
},
我的componentDidMount
后,检查我的isConnected
布尔值是否返回true 和我的accessToken
是否存在。如果两个条件都满足,我会为我的令牌进行API调用:
componentDidMount: function() {
if (this.state.isConnected && !this.state.accessToken){
api.getToken()
.then((responseData) => {
this.setState({
accessToken: responseData.access_token,
});
})
.done();
}
},
我还处理了componentWillUnmount
的事件监听器的删除:
componentWillUnmount: function() {
NetInfo.isConnected.removeEventListener(
'change',
this.handleConnectivityChange
);
},
我的事件监听器的handleConnectivityChange
回调是:
handleConnectivityChange: function(change) {
this.setState({
isConnected: change
})
console.log("I have changed!" + change)
},
最后,我的render
方法根据我的连接状态返回三件事之一:
render: function() {
if (this.state.isConnected === 'null') {
return (
<View style={styles.container}>
<Loading
loaded={this.state.isConnected} />
</View>
)
}
if (this.state.isConnected === 'false') {
return (
<View>
{AlertIOS.alert('You need to be connected to the internet!')}
</View>
)
}
return (
<TabBarIOS>
<Icon.TabBarItem
title='Home'
selected={this.state.selectedTab === 'products'}
iconName={'home'}
iconSize={20}
onPress={() => {
if (this.state.selectedTab !== 'products') {
this.setState({
selectedTab: 'products'
});
} else if (this.state.selectedTab === 'products') {
this.refs.productRef.popToTop();
}
}}>
{this.renderProductView()}
</Icon.TabBarItem>
<Icon.TabBarItem
title="Collections"
selected={this.state.selectedTab === 'collections'}
iconName={'list'}
iconSize={20}
onPress={() => {
if (this.state.selectedTab !== 'collections') {
this.setState({
selectedTab: 'collections'
});
} else if (this.state.selectedTab === 'collections') {
this.refs.collectionRef.popToTop();
}
}}>
{this.renderCollectionView()}
</Icon.TabBarItem>
<Icon.TabBarItem
title="About"
selected={this.state.selectedTab === 'about'}
iconName={'info'}
iconSize={20}
onPress={() => {
this.setState({
selectedTab: 'about'
});
}}>
{this.renderAboutView()}
</Icon.TabBarItem>
</TabBarIOS>
)
},
答案 0 :(得分:3)
我最终以下列方式构建我的应用程序:
首先,我在异步API调用中添加了catch
语句。它们看起来像这样:
getCollectionsData: function() {
api.getFeaturedCollections(this.props.accessToken)
.then((responseData) => {
this.setState({
featuredCollectionsDataSource: this.state.featuredCollectionsDataSource.cloneWithRows(responseData.collections),
loaded: true
})
})
.then(() => {
api.getAllCollections(this.props.accessToken)
.then((responseData) => {
this.setState({
allCollectionsDataSource: this.state.allCollectionsDataSource.cloneWithRows(responseData.collections),
})
})
})
.catch((error) => {
AlertIOS.alert('Error', 'You need to be connected to the internet')
})
.done()
},
我还将API调用逻辑移动到它自己的函数中,并在componentWillMount
期间调用它。
然后,我为AppState.IOS添加一个更改侦听器,它会检查在前台/后台运行的应用程序:
componentDidMount: function() {
AppStateIOS.addEventListener('change', this.handleAppStateChange);
},
componentWillUnmount: function() {
AppStateIOS.removeEventListener('change', this.handleAppStateChange);
},
我对这些更改的处理程序只是调用getCollectionsData
。