'Variables in state are not defined

I have the following screen:

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

export default class AuthorizationScreen extends Component {
  constructor(props) {
    super(props);
    this.state = { login: '', password: '' };
    this.onPressSignIn = this.onPressSignIn.bind(this);
  }

  onPressSignIn = () => {
    Alert.alert(this.state.login + this.state.password);
  };

  render() {
    return (
      <View styles={styles.container}>
        <View styles={styles.authorization}>
          <TextInput
            placeholder="Enter login"
            onChangeText={login => this.setState({ login })}
            value={login}
          />

          <TextInput
            placeholder="Enter password"
            onChangeText={password => this.setState({ password })}
            value={password}
          />

          <TouchableOpacity
            onPress={this.onPressSignIn}
          >

            <View>

              <Text>Search</Text>

            </View>

          </TouchableOpacity>
        </View>
      </View>

    );
  }
}

As you can see, there are 2 variables defined in state: login and password. This variables should keep the data from TextInputs. But when I run the project I have the following error:

ExceptionsManager.js:74 ReferenceError: login is not defined

This error is located at:
    in AuthorizationScreen (at SceneView.js:9)
    in SceneView (at SwitchView.js:12)
    in SwitchView (at createNavigator.js:61)
    in Navigator (at createAppContainer.js:429)
    in NavigationContainer (at App.js:54)
    in RCTView (at View.js:45)
    in View (at App.js:52)
    in Provider (at App.js:51)
    in App (at withExpoRoot.js:20)
    in RootErrorBoundary (at withExpoRoot.js:19)
    in ExpoRootComponent (at renderApplication.js:35)
    in RCTView (at View.js:45)
    in View (at AppContainer.js:98)
    in RCTView (at View.js:45)
    in View (at AppContainer.js:115)
    in AppContainer (at renderApplication.js:34)

I don't understand why does it happen, as I defined variables and bound the function, which works with this variables. So, what's the matter and how can I solve it?



Solution 1:[1]

Inside your render() method, to have access to the login and password state properties, you need this line:

const { login, password } = this.state

Solution 2:[2]

<View styles={styles.authorization}>
  <TextInput
    placeholder="Enter login"
    onChangeText={login => this.setState({ login })}
    value={this.state.login}
  />

  <TextInput
    placeholder="Enter password"
    onChangeText={password => this.setState({ password })}
    value={this.state.password}
  />
</View>

Solution 3:[3]

I think you should declare them (the 2 undefined variables) inside your constructor before assigning them to a state. i.e :

let login; let password;

Solution 4:[4]

Let me explain you some basics,

Consider an object,

const myObj = {key1:'value1',key2:'value2'}

Now if you want to access key2 from myObj, then you do this,

myObj.key2   //here you access object key using object name

Apply the same concept here,

this.state = { login: '', password: '' }

this.state is an object and contains login & password key's.

Now to use these key's you should access them using object name,

<TextInput
  placeholder="Enter login"
  onChangeText={login => this.setState({ login })}
  value={this.state.login}   //aceess `login` using `this.state`
/>

<TextInput
  placeholder="Enter password"
  onChangeText={password => this.setState({ password })}
  value={this.state.password}  //aceess `password` using `this.state`
/>

Solution 5:[5]

You should declare your state before the constructor, in the render function initialize somes const and use them to set your state :)

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

export default class AuthorizationScreen extends Component {

    state = {
        login: '',
        password: ''
    }

    constructor(props) {
        super(props);
        this.onPressSignIn = this.onPressSignIn.bind(this);
    }

    onPressSignIn = () => {
        Alert.alert(this.state.login + this.state.password);
    };

    render() {
        const {login, password} = this.state
        return (
            <View styles={styles.container}>
                <View styles={styles.authorization}>
                    <TextInput
                        placeholder="Enter login"
                        onChangeText={value => this.setState({ login: value })}
                        value={login}
                    />

                    <TextInput
                        placeholder="Enter password"
                        onChangeText={value => this.setState({ password: value })}
                        value={password}
                    />

                    <TouchableOpacity
                        onPress={this.onPressSignIn}
                    >

                    <View>

                        <Text>Search</Text>

                    </View>

                    </TouchableOpacity>
                </View>
            </View>

        );
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Julien LemaƮtre
Solution 2
Solution 3 elolelo
Solution 4 ravibagul91
Solution 5 baddeveloper