不断检查整个应用程序的网络连接

时间:2015-07-09 03:51:31

标签: react-native

我正在开发一个从外部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>
      )
  },

1 个答案:

答案 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