При запуске this._login `this.navigation` имеет значение` undefined`

Я пытаюсь перемещаться внутри функции _login, а не внутри нее. В функции this.props.navigation есть undefined. Что там не так?

import React from 'react';
import { StyleSheet, Form, View, Text } from 'react-native';
import { StackNavigator } from 'react-navigation';
import { Button, FormValidationMessage, FormLabel, FormInput } from 'react-native-elements';
import { AgendaScreen } from './AgendaScreen';

class HomeScreen extends React.Component {

  static navigationOptions = {
    title: 'Please sign in',
  };

  render() {
    return (
      <View style = {styles.container}>
        <FormLabel>Username</FormLabel>
        <FormInput onChangeText = {this.inputChanged} />
        <FormValidationMessage>{'This field is required'}</FormValidationMessage>
        <FormLabel>Password</FormLabel>
        <FormInput secureTextEntry = {true} onChangeText = {this.inputChanged} />
        <FormValidationMessage>{'This field is required'}</FormValidationMessage>
        <Button raised onPress = {this._login} title = "Sign in" />
      </View>
    );
  }

  inputChanged() {
    console.info('adfasdf');
  }

  _login() {
    this.props.navigation.navigate('Agenda');
    console.info('Logging in');
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff'
  }
});

export default StackNavigator({
  Home: HomeScreen,
  Agenda: AgendaScreen
});
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
1
30
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вам нужно привязать метод _login к вашему классу:

<Button raised onPress = {this._login.bind(this)} title = "Sign in" />

Или объявите метод _login как стрелочную функцию:

 _login = () => {
    this.props.navigation.navigate('Agenda');
    console.info('Logging in');
  }

Ах, супер! Я получил старый добрый bind, но мне нужно прочитать значение стрелочных функций в реакции.

Asken 04.05.2018 15:54

У стрелочных функций нет собственного контекста, поэтому вам не нужно изменять контекст this в обратных вызовах и создавать оболочки.

Artem Mirchenko 04.05.2018 15:59

При передаче _login вашему компоненту Button вы теряете значение this.

Решением было бы привязать this к _login, например, внутри constructor:

this._login = this._login.bind(this);

Или вы можете использовать Arrow functions:

<Button raised onPress = {() => { this._login() }} title = "Sign in" />

Во-первых, вы пытаетесь использовать this внутри функции, которая будет вызываться другим компонентом / функцией (Button).

Этот Button не знает this, потому что он не в том же контексте.

Вам нужно привязать метод к текущему объекту.

Для этого рекомендую привязать его в конструкторе.

class HomeScreen extends React.Component {
    constructor(props, context) {
        super(props, context);
        this._login = this._login.bind(this);
    }

    render() {
        return (
            <View style = {styles.container}>
                {/* MORE CODE */}
                <Button raised onPress = {this._login} title = "Sign in" />
            </View>
        );
    }

    // * MORE CODE *
}

Во-вторых, это нужно делать в конструкторе, а не в строке.

Если это делается встроенным, тогда onPress назначается функция НОВЫЙ, и response будет повторно визуализировать эту часть без необходимости.

То же самое происходит со встроенными стрелочными функциями.

РЕДАКТИРОВАТЬ

Эта вторая часть применяется только тогда, когда:

  1. Использование PureComponent
  2. Использование shouldComponentUpdate для сопоставления реквизита

Тем не менее, встроенно вы создаете другую функцию каждый раз, когда реагирует на рендеринг компонента. Все еще плохая практика.

РЕДАКТИРОВАТЬ 2 (ES6)

Чтобы предотвратить использование constructor, вы можете использовать стрелочные функции, но по-другому. Как это.

class MyComponent extends React.PureComponent {
  doWork = () => {
    // doing some work here.
  }

  render() {
    return <Text onPress = {this.doWork}>Do Some Work</Text>
  }

}

Таким образом, вы создаете функцию только один раз за всю жизнь.

Другие вопросы по теме