Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

this.state is undefined during onPress event in react native

Hello i new in react native, my code is:

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

import Style from './styles/signin';
import Button from '../common/button';

export default class SignIn extends Component {
  constructor(props) {
    super(props);
    this.state = {
      email: '',
      password: ''
    };
  }

  render(){
    return(
      <View style={Style.container}>
        <Text style={Style.label}>Email</Text>
        <TextInput
          style={Style.input}
          onChangeText={(text) => this.setState({email: text})}
          value={this.state.email}
        />
        <Text style={Style.label}>Password</Text>
        <TextInput
          style={Style.input}
          onChangeText={(text) => this.setState({password: text})}
          value={this.state.password}
          secureTextEntry={true}
        />
        <Button text={'Sign in'} onPress={this.onPress}/>
      </View>
    );
  }
  onPress(){
    console.log(this.state.email);
  }
}

When i fill this form and press sign in, i have this error message: "Cannot read property 'email' of undefined". Thank you for the help!

like image 515
ImPuLsE Avatar asked May 09 '16 18:05

ImPuLsE


1 Answers

This is a binding issue. The simplest solution will be to change your JSX for the button tag like so:

<Button text={'Sign in'} onPress={this.onPress.bind(this)} />

ES6 classes lose the autobinding you may have been used to with es5 react.createClass. You have to be more conscious of your binding when using ES6 for react components.

Another option is to bind the method in your constructor like so:

  constructor(props) {
    super(props);
    this.state = {
      email: '',
      password: ''
    };

    this.onPress = this.onPress.bind(this)
  }

Or you could even utilize a fat arrow es6 syntax function to maintain the 'this' binding to the component you're creating:

<Button text={'Sign in'} onPress={() => this.onPress()} />

UPDATE:

To update this again, if your environment supports some ES7 features (which I believe react-native built from react-native init or create-react-native-app shoudl do) you can use this notation to auto-bind your class methods that utilize the this keyword.

// This is auto-bound so `this` is what you'd expect
onPress = () => {
    console.log(this.state.email);
};

instead of

// This is not auto-bound so `this.state` will be `undefined`
onPress(){
  console.log(this.state.email);
}

The best options are to use the ES7 feature if available or to bind in your constructor. Using an anonymous function onPress={() => this.onPress()} or onPress={this.onPress.bind(this)} directly on your Button is much less favorable for performance reasons.

like image 69
jmancherje Avatar answered Oct 20 '22 03:10

jmancherje