我正在使用带有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升级了。不太确定这条信息是否有帮助。
答案 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);
我只粘贴了更改的功能。