ReferenceError:找不到变量:React Native 0.60.4中的状态

时间:2019-08-19 09:02:50

标签: reactjs react-native react-native-android react-native-router-flux react-state

我正在使用带有react-native-router-flux 4.0.6的React native 0.60.4。 我有一个登录组件,该组件工作正常,但是在用户更改密码后将用户重定向到登录屏幕时,会弹出上述错误,并且应用程序崩溃。

我尝试在ComponentDidMount()中打印状态变量-它被打印。在初始化状态变量的构造函数中,所有日志都会被打印出来。 发布此错误会弹出并导致应用崩溃。

错误消息的一部分:

  

[08:42:09]我| ReactNativeJS▶︎登录组件DidMount

     

[08:42:09] E | ReactNativeJS▶︎ReferenceError:找不到变量:状态

我相信代码没有问题,因为无论何时加载应用程序,它都可以正常工作。

代码:

    import * as React from 'react';
    // import React, { Component } from "react";
    import {
        StyleSheet,
        Text,
        TouchableOpacity, 
        ToastAndroid,
        AppState,
        Dimensions,
        View,
        ImageBackground,
        Image,
        DeviceEventEmitter,
        LayoutAnimation,
        UIManager,
        Platform,
        Keyboard
        // AsyncStorage
        // NetInfo
    } from "react-native";

    import AsyncStorage from '@react-native-community/async-storage';
    import NetInfo  from '@react-native-community/netinfo';

    import { Actions } from 'react-native-router-flux'; 
    import { Bars } from 'react-native-loader';
    import Nointernet from './NoInternet';
    import axios from 'axios';
    import TextField from './lib/TextField';
    import { PermissionsAndroid } from 'react-native';
    import firebase from 'react-native-firebase';

    let deviceWidth = Dimensions.get('window').width;
    let elementWidth = 0.8*deviceWidth;
    let screenHeigth = Dimensions.get('window').height;

    const unsubscribe=NetInfo.addEventListener((change)=>{ this.handleConnectivityChange });

    class LoginScreen extends React.Component {
        constructor(props) {
            console.log("Props done");
            super(props);
            console.log("State issue");
            this.state = { 
                appState: AppState.currentState,  
                hidePwd:true,
                pntoken: '', 
                username: '', 
                passwd: '', 
                text: '', 
                checkinternet:false,
                nointernet:false,
                isLoading: false ,
                visibleHeight: Dimensions.get('window').height ,

            logo_height:100,
            logo_width:100,
            pwd_backup:''

        };
        console.log("State initialized");
        this.handleConnectivityChange = this.handleConnectivityChange.bind(this);
        this._handleAppStateChange = this._handleAppStateChange.bind(this);
        this.requestLocationPermission = this.requestLocationPermission.bind(this);

        if (Platform.OS === 'android') {
          UIManager.setLayoutAnimationEnabledExperimental(true);
        }
    }

    async getfcmtooken(){
        let pn_token = await firebase.messaging().getToken();
        if(pn_token){
            console.log("PNTOKEN")
            // if(this.state!=undefined)
            //     this.setState({ pntoken: pn_token});
            console.log("have TOKN");
            // if(this.state!=undefined)
            //     console.log(this.state.pntoken);
            this.updateToken(pn_token);
        }
        else{
            console.log("Loggged in. PN_TOKEN")
            this.tokenRefreshListener = firebase.messaging().onTokenRefresh((pn_token) => {
                console.log('response getfcmtooken');
                if (pn_token) {
                    console.log("got token")
                    // if(this.state!=undefined)
                    //     this.setState({ pntoken: pn_token})
                    this.updateToken(pn_token);
                    // if(this.state!=undefined)
                    //     console.log(this.state.pntoken);
                }
            });
            console.log('getfcmtooken')
        }   
    }

    updateToken(token) {
        console.log('App updateToken');
        AsyncStorage.getItem('org_id').then((orgId) => {
            if(orgId != null){
                console.log('orgId');
                console.log(orgId);
                let org_id = JSON.parse(orgId);
                console.log('org_id');
                console.log(org_id);
                AsyncStorage.getItem('email').then((useremail) => {
                    let email = JSON.parse(useremail);
                    if(email){
                        console.log('email');
                        AsyncStorage.getItem('token').then((tokenvalue) => {
                            if(tokenvalue!=null){
                                console.log('user_id');
                                console.log(tokenvalue);
                                let tokenV = JSON.parse(tokenvalue);
                                console.log("PN TOKEN");
                                console.log(token);

                                axios({
                                    method: 'PUT',
                                    url: this.props.apiurl+'/pushnotification/updatetoken', 
                                    data: JSON.stringify({
                                        email: email,
                                        pntoken: token,
                                    }), 
                                    timeout: 30000,
                                    headers:{ 
                                        Accept: 'application/json',
                                        'Content-Type': 'application/json',
                                        authorization:tokenV
                                    }
                                }).then((response)=>{
                                    console.log("RESPONSE")
                                    console.log(response);
                                })
                                .catch(error=>{
                                    console.log("ERROR")
                                    console.log(error);
                                })
                                // return fetch(this.props.apiurl+'/pushnotification/updatetoken', {
                                //     method: 'PUT',
                                //     headers: {
                                //         Accept: 'application/json',
                                //         'Content-Type': 'application/json',
                                //     },
                                //     body: JSON.stringify({
                                //         email: email,
                                //         pntoken: token,
                                //     }),
                                // })
                                // .then((response) => {
                                //     console.log('222222222222'); 
                                //     console.log(response);
                                //     response.json()
                                // })
                                // .then((responseJson) => {
                                //     console.log('kkkkkkkkkkkkkkk'); 
                                //     console.log(responseJson);
                                // })
                                // .catch((error) => {
                                //     console.log('error'); 
                                //     console.log(error);
                                // });
                            }
                        });
                    }
                });
            }
        });
    }

    async requestCameraPermission() {
        try {
            const granted = await PermissionsAndroid.request(
                PermissionsAndroid.PERMISSIONS.CAMERA,{
                    'title': 'Camera Permission',
                    'message': 'needs access to your camera '
                }
            )
            if (granted) {
                console.log("You can use the camera")
                this.requestLocationPermission()
            } 
            else {
                console.log("Camera permission denied")
            }
        } catch (err) {
            console.warn(err)
        }
    }

    async requestLocationPermission() {
        try {
            const granted = await PermissionsAndroid.request(
                PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
                {
                    'title': 'Camera Permission',
                    'message': 'needs access to your location '
                }
            )
            if (granted) {
                console.log("You can use the location")
            } 
            else {
                console.log("location permission denied")
            }
        } 
        catch (err) {
            console.warn(err)
        }
    }

    componentDidMount() {
        console.log(this.state);
        console.log("login componentDidMount");
        this.getfcmtooken();
        NetInfo.fetch().then((connectionInfo) => {
            if(connectionInfo.type != 'none'){
                console.log("NETINFO");
                this.setState({ checkinternet : false ,nointernet : false });
                this.requestCameraPermission();
            }
            else{
                this.setState({ checkinternet : false ,nointernet : true });
            }
        })
        .catch((response)=>{
            console.log(response);
        });

        AppState.addEventListener('change', this._handleAppStateChange);

        this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this.keyboardDidShow.bind(this))
        this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this.keyboardDidHide.bind(this))
    }

    _handleAppStateChange = (nextAppState) => {
        console.log("CHECKING STATE");
        if (this.state.appState.match(/active/) && nextAppState === 'background') {
          console.log('App has come to the background!')
        }
        console.log("CHECKED STATE")
        this.setState({appState: nextAppState});
        console.log("NEW STATE SET");
        NetInfo.fetch()
        .then((connectionInfo) => {
            if(connectionInfo.type != 'none'){
                this.setState({ nointernet : false });
            }
            else{
                this.setState({ nointernet : true });
            }
        })
        .catch((response)=>{
            console.log(response);
        });
    }

    handleConnectivityChange() {

        NetInfo.fetch().then((connectionInfo) => {
            if(connectionInfo.type != 'none'){
                console.log("INTERNET CHECK 1")
                this.setState({ nointernet : false });
                console.log("INTERNET CHECKED 1")
            }
            else{
                console.log("INTERNET CHECK 2")
                this.setState({ nointernet : true });
                console.log("INTERNET CHECKED 2")
            }
        })
        .catch((response)=>{
            console.log(response);
        });
    }

    componentWillUnmount() {
        AppState.removeEventListener('change', this._handleAppStateChange);
        NetInfo.removeEventListener('connectionChange', this.handleConnectivityChange );
        // unsubscribe();
        this.keyboardDidShowListener.remove()
        this.keyboardDidHideListener.remove()
    }

    keyboardDidShow (e) {
        console.log('Key Event');
        console.log(Dimensions.get('window').height+' - '+e.endCoordinates.height);
        let newSize = Dimensions.get('window').height - e.endCoordinates.height
        console.log('new size')
        console.log(newSize);
        console.log('wind_width')
        console.log(Dimensions.get('window').width);
        LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)
        this.setState({
            visibleHeight: newSize,
            logo_width:50,
            logo_height:50
        })
    }

    keyboardDidHide (e) {
        LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)
        this.setState({
            visibleHeight: Dimensions.get('window').height,
            logo_height:100,
            logo_width:100
        })
    }  

    managePwd(){ 
        this.setState({
            hidePwd:!this.state.hidePwd
        })
    }

    login(){
        if(this.state.username != ''){
            let reg = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/ ;
            if(reg.test(this.state.username) === true){
                if(this.state.passwd != ''){
                    return fetch(this.props.apiurl+'/mobilelogin', {
                        method: 'POST',
                        headers: {
                            Accept: 'application/json',
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({
                            email: this.state.username,
                            password: this.state.passwd,
                            pntoken: this.state.pntoken,
                        }),
                    })
                    .then((response) => response.json())
                    .then((responseJson) => {
                        if(responseJson.statusCode == 200){
                                this.setState({
                                isLoading: false,
                                text: responseJson.result.authenticateUser.userRole,
                                dataSource: responseJson
                            }, function() {
                                try{
                                    console.log('TOKEN');
                                    console.log(JSON.stringify(responseJson.result.authenticateUser.token));
                                    AsyncStorage.setItem('token', JSON.stringify(responseJson.result.authenticateUser.token)); 
                                    AsyncStorage.setItem('email', JSON.stringify(responseJson.result.authenticateUser.email)); 
                                    AsyncStorage.setItem('userRole', JSON.stringify(responseJson.result.authenticateUser.userRole)); 
                                    AsyncStorage.setItem('org_id', JSON.stringify(responseJson.result.authenticateUser.orgId)); 
                                    AsyncStorage.setItem('user_id', JSON.stringify(responseJson.result.authenticateUser.userId)); 
                                    this.getfcmtooken();
                                    AppState.removeEventListener('change', this._handleAppStateChange);
                                    unsubscribe();
                                    // NetInfo.removeEventListener('connectionChange', this.handleConnectivityChange );
                                    Actions.landing();
                                } catch (error) {
                                    console.log(error)
                                }
                            });
                        }
                        else{
                            ToastAndroid.show(responseJson.authenticateUser.statusMessage,ToastAndroid.LONG);
                        }
                    })
                    .catch((error) => {
                        console.log('error'); 
                        console.log(error);
                    });
                }
                else{
                  ToastAndroid.show('Password is mandatory',ToastAndroid.LONG);
                }
            }
            else{
              ToastAndroid.show('Email is not in correct form',ToastAndroid.LONG);
            }
        }
        else{
            ToastAndroid.show('Email is mandatory',ToastAndroid.LONG);
        }
    }

    render(){
        console.log("RENDERING ...");
        if(this.state.checkinternet){
            console.log("LOADING...CONNECTION ")
            return  <View style={{flex:1, backgroundColor: '#fff'}}>
                        <View style={{height:screenHeigth-60, justifyContent:'center',alignItems:'center'}}>
                            <Bars size={25} color="#eb5828" />
                        </View>
                    </View>;
        }
        if (this.state.nointernet) {
            return  <View>
                        <Nointernet/>
                    </View>;
        }
        return (
                <View style={[styles.container,{height: this.state.visibleHeight}]}>
                    <ImageBackground
                      style={[styles.topLogo1,{height: this.state.visibleHeight}]}
                      source={require('../assets/Background.png')}
                    >
                        <View style={styles.upperContainer}>
                            <View style={styles.signintextContainer}>
                                <Image style={{height:this.state.logo_height,width:this.state.logo_width}} source={require('../assets/WhiteLogo.png')}/>
                                <Text style={styles.appname}>Smart Timer</Text>
                            </View>
                        </View>
                        <View style={styles.formContainer}>
                            <View style={[{width:elementWidth},styles.elementcontainer]}>
                                <TextField 
                                    label={'E-mail ID'} 
                                    highlightColor={'#fff'} 
                                    onChangeText={(username) => this.setState({username})}
                                    value={this.state.username}
                                    keyboardType='email-address'
                                    autoCapitalize='none'
                                    textColor='#fff'
                                    wrapperStyle={{ height: 60 }}
                                    labelStyle={{ color: '#fff', fontFamily: 'Lato-Regular' }}
                                />
                            </View>
                            <View style={[{width:elementWidth},styles.elementcontainer]}>
                                <View style={styles.textBoxBtnHolder}>
                                    <TextField 
                                        label={'Password'} 
                                        highlightColor={'#fff'} 
                                        secureTextEntry={this.state.hidePwd}
                                        onChangeText={(passwd) => this.setState({passwd})}
                                        value={this.state.passwd}
                                        autoCapitalize='none'
                                        textColor='#fff'
                                        wrapperStyle={{ height: 60 }}
                                        labelStyle={{ color: '#fff', fontFamily: 'Lato-Regular' }}
                                    />
                                    <TouchableOpacity style={styles.visibilityBtn} onPress={this.managePwd.bind(this)} >
                                        <Image style={{ marginRight:10, height: 25,width: 25 }} source={this.state.hidePwd?require('../assets/private.png'):require('../assets/view.png')}/>
                                    </TouchableOpacity>
                                </View>
                            </View>
                            <TouchableOpacity style={[ {width:elementWidth},styles.buttonRaised ]} onPress={this.login.bind(this)} >
                                <Text style={[ styles.buttonText ]}>Login</Text>
                            </TouchableOpacity>
                            <View style={styles.signupTextContainer}>
                                <View>
                                    <TouchableOpacity onPress={() => Actions.forgotpassword({apiurl:this.props.apiurl})} >
                                        <Text style={[ styles.signupText ]}>Forgot Password  | </Text>
                                    </TouchableOpacity>
                                </View>
                                <View>
                                    <TouchableOpacity onPress={() => Actions.register({apiurl:this.props.apiurl})} >
                                        <Text style={[ styles.signupTextblack ]}> Sign Up</Text>
                                    </TouchableOpacity>
                                </View>
                            </View>
                        </View>
                    </ImageBackground>
                </View>
            );
    }
}

在我从react-native-router-flux从^ 4.0.0-beta.28升级到^ 4.0.6之前,我使这段代码运行良好,然后又将react-native-router-flux从^ 4.0.0-beta.28升级了。不太确定这条信息是否有帮助。

2 个答案:

答案 0 :(得分:0)

好吧,您必须直接使用状态而不是导致此问题的this.state。在构造函数中初始化的任何没有数据类型的事物,都应考虑使用this运算符进行初始化,以使其在整个类中都可以使用this.abc进行访问。

答案 1 :(得分:0)

这是因为您的unsubscribe函数是在类之外定义的,而该函数在login函数中被调用,此外,当您在登录名中调用unsubscribe时,它应该只是{ {1}}

NetInfo.removeEventListener(...)

应更改为

NetInfo.addEventListener((change) => { this.handleConnectivityChange });

所以最后应该是这样的:

this.unsubscribe = NetInfo.addEventListener('connectionChange', this.handleConnectivityChange);

我只粘贴了更改的功能。