React Native NetInfo'connectionChange'事件未被触发

时间:2017-09-25 06:41:11

标签: javascript android ios reactjs react-native

我正在研究两个PoC。 1)RNRestAPI。 2)RNNavigate。

在RNRestAPI中,index.android.js和index.ios.js都是这样的;

import React, { Component } from 'react';
import {
  AppRegistry,
  View
} from 'react-native';
import Login from './app/screens/Login/Login';
import About from './app/screens/About/About';

export default class RNRestAPI extends Component {
  render() {
    return (
      <View style={{flex:1}}>
        <Login />
      </View>
    );
  }
}

AppRegistry.registerComponent('RNRestAPI', () => RNRestAPI);

Login.js就是这样;

import React, { Component } from 'react';
import {
  AppRegistry,
  View,
  TextInput,
  StyleSheet,
  Button,
  Text,
  Alert,
  TouchableHighlight,
  Platform,
  Image,
  NetInfo,
  ProgressBarAndroid,
  ProgressViewIOS
} from 'react-native';
import I18n from '../../resources/strings/i18n';
import Colors from '../../resources/styles/colors';
import Dimensions from '../../resources/styles/dimensions';
import Styles from '../../resources/styles/styles';
import Config from '../../config';

export default class Login extends Component {
  constructor() {
    super();

    this.state = {
      username:'',
      password:'',
      buttonLoginDisabled:false,
      isConnected:false
    }

    // I18n.locale = 'en';
  }

  componentWillMount() {
    NetInfo.addEventListener(
      'connectionChange',
      this.handleConnectivityChange.bind(this)
    );
  }

  componentWillUnmount() {
    NetInfo.removeEventListener('connectionChange', handleConnectivityChange);
  }

  handleConnectivityChange(connectionInfo) {
    console.log('First change, type: ' + connectionInfo.type + ', effectiveType: ' + connectionInfo.effectiveType);

    if(connectionInfo.type === 'none') {
      this.setState({
        isConnected:false,
        buttonLoginDisabled:true
      });
    } else {
      this.setState({
        isConnected:true,
        buttonLoginDisabled:false
      });
    }
  }

  onLoginClicked() {
    var valid = this.validateLoginForm();

    if(valid === true) {
      this.setState({
        buttonLoginDisabled:true
      });

      this.makeLoginRequest();
    } else {
      Alert.alert(I18n.t('dialogLoginInvalidTitle'), I18n.t('dialogLoginInvalidMessage'));
    }
  }

  validateLoginForm() {
    if(this.state.username === '') {
      return false;
    }

    if(this.state.password === '') {
      return false;
    }

    return true;
  }

  makeLoginRequest() {
    fetch('http://webapitest', {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'MobilePlatformId': Config.MobilePlatformId,
        'ApplicationId': Config.ApplicationId,
        'Version': '1.9.6'
      },
      body: JSON.stringify({
        Username: this.state.username,
        Password: this.state.password
      })
    })
    .then((response) => response.json())
    .then((responseJson) => {
      console.log(responseJson);

      if(responseJson.Token !== null) {
        console.log('login successful');
      } else {
        this.setState({
          buttonLoginDisabled:false
        });

        Alert.alert(I18n.t('dialogInvalidLoginTitle'), I18n.t('dialogInvalidLoginMesage'));
      }
    })
    .catch((error) => {
      console.log(eror);

      this.setState({
        buttonLoginDisabled:false
      });
    })
  }

  setUsername(value) {
    this.setState({
      username:value
    });
  }

  setPassword(value) {
    this.setState({
      password:value
    });
  }

  onMoreClicked() {
    Alert.alert(I18n.t('dialogLearnMoreTitle'), I18n.t('dialogLearnMoreMesage'));
  }

  getLoginButtonStyle() {
    if(this.state.buttonLoginDisabled) {
      return styles.buttonLoginDisabled;
    } else {
      return styles.buttonLogin;
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <View>
          <Image source={require('../../resources/images/facilit_logo_welcome.png')}
            style={{width:266, height:50, resizeMode:Image.resizeMode.cover}} />
        </View>
        <View style={styles.wrapperLoginInput}>
          <TextInput
            keyboardType='default' 
            placeholder={I18n.t('username')} 
            returnKeyType='next' 
            onChangeText={(value) => this.setUsername(value)}
            style={Styles.primaryTextInput} />

          <TextInput secureTextEntry={true} 
            placeholder={I18n.t('password')}
            onChangeText={(value) => this.setPassword(value)}
            style={Styles.primaryTextInput} />

          <TouchableHighlight onPress={this.onLoginClicked.bind(this)}
            style={{marginTop:(Platform.OS === 'ios') ? 10 : 30}}
            underlayColor='#00000000'
            disabled={this.state.buttonLoginDisabled}>
            <View style={this.getLoginButtonStyle()}>
              <Text style={styles.buttonLoginText}>{I18n.t('login')}</Text>
            </View>
          </TouchableHighlight>


          <View style={styles.wrapperLearnMoreLink}>
            <TouchableHighlight onPress={this.onMoreClicked.bind(this)}
              underlayColor='#00000000'>
              <Text style={styles.learnMoreLink}>{I18n.t('learnMore')}</Text>
            </TouchableHighlight>
          </View>
        </View>
      </View> 
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex:1,
    backgroundColor:Colors.primaryBlue,
    justifyContent:'center',
    alignItems:'center'
  },
  wrapperLoginInput: {
    width:300,
    marginTop:100
  },
  buttonLogin: {
    backgroundColor:Colors.primaryYellow,
    alignItems:'center',
    height:Dimensions.primaryButtonHeight,
    justifyContent:'center',
    borderRadius:Dimensions.primaryButtonBorderRadius,
    borderWidth:Dimensions.primaryButtonBorderWidth,
    borderColor:Colors.primaryButtonBorderColor,
  },
  buttonLoginDisabled: {
    backgroundColor:Colors.primaryButtonDisabledGray,
    alignItems:'center',
    height:Dimensions.primaryButtonHeight,
    justifyContent:'center',
    borderRadius:Dimensions.primaryButtonBorderRadius,
    borderWidth:Dimensions.primaryButtonBorderWidth,
    borderColor:Dimensions.primaryButtonBorderColor,
  },
  buttonLoginText: {
    fontSize:Dimensions.primaryButtonFontSize,
    color:Colors.primaryButtonFontColor
  },
  wrapperLearnMoreLink: {
    alignItems:'center',
    marginTop:150,
  },
  learnMoreLink: {
    color:Colors.secondaryTextColor,
    textDecorationLine:'underline'
  }
});

AppRegistry.registerComponent('Login', () => Login);

重要位是componentWillMount()handleConnectivityChange(connectionInfo)。它们按预期工作,我的代码处理在线/离线方案。

第二个PoC(RNNavigate)基本上是RNRestAPI的副本,但包含react-navigation https://reactnavigation.org/。在用户成功登录我的应用程序后,我基本上尝试为我的应用程序创建导航。因此,我对我的代码进行了以下修改。

1)创建App.js

import React, { Component } from 'react';
import {
  AppRegistry,
  View
} from 'react-native';

import Login from './app/screens/Login/Login';
import About from './app/screens/About/About';
import FacilitySearch from './app/screens/FacilitySearch/FacilitySearch';

import { StackNavigator } from 'react-navigation';

export default class RNNavigate extends Component {
  render() {
    return (
      <View style={{flex : 1}}>
        <RNNavigateApp />
      </View>
    );
  }
}

const RNNavigateApp = StackNavigator({
    Login : {
      screen : Login,
      navigationOptions : ({navigation}) => ({
        header : null
      })
    },
    About : { screen : About },
    FacilitySearch : { 
      screen : FacilitySearch,
      navigationOptions : ({
        headerLeft : null
      })
    }
});

AppRegistry.registerComponent('RNNavigate', () => RNNavigate);

2)将index.android.js和index.ios.js修改为;

import './App.js';

Login.js不受影响。但connectionChange事件不再被解雇。如果我在使用React Navigate方面做错了什么,我会非常感谢任何专家帮助,指导我为什么不再解雇或教育我。

1 个答案:

答案 0 :(得分:1)

对我来说,该事件未触发,因为在<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />中添加了AndroidManifest.xml后,我没有重新启动我的react-native服务器。

杀死您的服务器,然后重启它,然后应该会触发。