2017-07-25 70 views
0

我在組件內的函數中訪問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

回答

1

如果傳遞給Touchable,您的登錄函數應該被綁定以訪問正確的this。 可以固定通過這些任何一種途徑:

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

OR: 

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

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

2

在構造函數替換約束力的聲明類似下面

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是未定義的 –

-1

我有一個類似的問題。對我來說,這個問題引發了,因爲我在編寫代碼時遇到了「熱重新加載」的原生反應。

這基本上意味着我要求一個未定義的變量,因爲構造函數沒有被調用(該應用程序在編碼時是活動的)。

一旦你退出/開始或只是重新加載應用程序,那麼它確實定義了狀態(因爲在初始加載應用程序時它調用構造函數())。

這可能是你的問題嗎?