react-native:在登录函数中未定义`this.state`

问题描述:

我在组件内的函数中访问this.state时遇到问题。react-native:在登录函数中未定义`this.state`

我总是得到 “未定义不是对象this.state.usernamethis.state.password” 错误

SimpleForm.js

import Expo from 'expo'; 
import React from 'react'; 
import { StackNavigator, DrawerNavigator } from 'react-navigation'; 
import App from './App'; 
import RegisterForm from './register'; 
import { View, Text, TextInput, Image, TouchableOpacity, AsyncStorage, StyleSheet } from 'react-native'; 
import { YourRestApi } from './constants/api3'; 

class SimpleForm extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { username: '', password: '', datas: '' }; 
    this.login = this.login.bind(this, this.state.username, this.state.password); 
    } 
    componentWillMount() { 
    this.login(); 
    } 

    registerscreen =() => { 
    this.props.navigation.navigate('Register'); 
    } 


    login() { 
    YourRestApi(this.state.username, this.state.password) 
     .then((response) => { 
     console.log(response.success); 
     this.setState({ loading: false, datas: response }); 
     }); 
    if (this.state.datas.success === true) { 
     const info = this.state.datas.message; 

     AsyncStorage.setItem('info', JSON.stringify(info)); 
     this.props.navigation.navigate('SecondScreen'); 
    } else { 
     alert(this.state.datas.message); 
    } 
    } 

    render() { 
    const { navigate } = this.props.navigation; 
    return (
     <View style={styles.container}> 
     <Image source={require('./assets/img/sd.png')} style={styles.backgroundImage}> 
      <View style={styles.content}> 
      <Text style={styles.logo}>Toto Prediction </Text> 
      <View style={styles.inputContainer}> 

       <TextInput 
       underlineColorAndroid='transparent' style={styles.input} 
       onChangeText={(username) => this.setState({ username })} 
       value={this.state.username} placeholder='username' 
       /> 

       <TextInput 
       secureTextEntry underlineColorAndroid='transparent' style={styles.input} 
       onChangeText={(password) => this.setState({ password })} 
       value={this.state.password} placeholder='password' 
       /> 
      </View> 
      <TouchableOpacity onPress={this.login} style={styles.buttonContainer}> 
       <Text style={styles.buttonText}>Login</Text> 
      </TouchableOpacity> 
      this._onPressGet.bind(this) 
      <TouchableOpacity onPress={this.registerscreen} style={styles.buttonContainer}> 
       <Text style={styles.buttonText}>Register</Text> 
      </TouchableOpacity> 
      </View> 
     </Image> 
     </View> 

    ); 
    } 
} 
const styles = StyleSheet.create({ 
    container: { 
    flex: 1, 
    }, 
    backgroundImage: { 
    flex: 1, 
    alignSelf: 'stretch', 
    width: null, 
    justifyContent: 'center', 
    }, 
    content: { 
    alignItems: 'center', 
    }, 
    logo: { 
    color: 'white', 
    fontSize: 40, 
    fontStyle: 'italic', 
    fontWeight: 'bold', 
    textShadowColor: '#252525', 
    textShadowOffset: { width: 2, height: 2 }, 
    textShadowRadius: 15, 
    marginBottom: 20, 
    }, 
    inputContainer: { 
    margin: 20, 
    marginBottom: 0, 
    padding: 20, 
    paddingBottom: 10, 
    alignSelf: 'stretch', 
    borderWidth: 1, 
    borderColor: '#fff', 
    backgroundColor: 'rgba(255,255,255,0.2)', 
    }, 
    input: { 
    fontSize: 16, 
    height: 40, 
    padding: 10, 
    marginBottom: 10, 
    backgroundColor: 'rgba(255,255,255,1)', 
    }, 
    buttonContainer: { 
    margin: 20, 
    padding: 20, 
    backgroundColor: 'blue', 
    borderWidth: 1, 
    borderColor: '#fff', 
    backgroundColor: 'rgba(255,255,255,0.6)', 
    }, 
    buttonText: { 
    fontSize: 16, 
    fontWeight: 'bold', 
    textAlign: 'center', 
    }, 
}); 
const SimpleApp = DrawerNavigator({ 
    Onescreen: { screen: SimpleForm }, 
    SecondScreen: { screen: App }, 
    Register: { screen: RegisterForm }, 
}); 
Expo.registerRootComponent(SimpleApp); 

Api3.js

export function YourRestApi(username1, password1) { 
    fetchlogin(username1, password1); 
} 
function fetchlogin(username1, password1) { 
    const details = { 
    username: username1, 
    password: password1, 
    }; 
    const formBody = Object.keys(details).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(details[key])}`).join('&'); 

    fetch('https://*********************', { 
    method: 'POST', 
    headers: { 
     Accept: 'application/json', 
     'Content-Type': 'application/x-www-form-urlencoded', 
    }, 
    body: formBody, 
    }) 
    .then((response) => response.json()) 
    .then((response) => { 
     console.log('requestAppInstallation success ', response); 
     return response; 
    }) 
    .done(); 
} 

我试图登录绑定到this.state,但没有工作

我已经检查了其他问题,但没有任何工作

任何想法可能会导致这种情况?

+0

您可以使用https://www.npmjs.com/package/core-decorators#autobind并自动登录登录方法到类 – Raymond

如果传递给Touchable,您的登录函数应该被绑定以访问正确的this。 可以固定通过这些任何一种途径:

<TouchableOpacity onPress={this.login.bind(this)} ...> 

OR: 

<TouchableOpacity onPress={() => this.login()} ...> 
+0

我所做的就是声明函数,例如functionName =()=> {}绑定它以及 – user1780729

在构造函数替换约束力的声明类似下面

constructor(props) { 
    super(props); 
    this.state = { username: '', password: '', datas: '' }; 
    this.login = this.login.bind(this); 
    } 
+0

^比我的回答更好,没有注意到你正在做的古怪绑定在ctor –

+0

不工作它不工作我得到同样的错误YourRestApi(this.state.username,this.state.password)this .state是未定义的 –

我有一个类似的问题。对我来说,这个问题引发了,因为我在编写代码时遇到了“热重新加载”的原生反应。

这基本上意味着我要求一个未定义的变量,因为构造函数没有被调用(该应用程序在编码时是活动的)。

一旦你退出/开始或只是重新加载应用程序,那么它确实定义了状态(因为在初始加载应用程序时它调用构造函数())。

这可能是你的问题吗?