При запуске this._login `this.navigation`is` undefined` - PullRequest
0 голосов
/ 04 мая 2018

Я пытаюсь перемещаться внутри функции _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.log('adfasdf');
  }

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

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

export default StackNavigator({
  Home: HomeScreen,
  Agenda: AgendaScreen
});

Ответы [ 3 ]

0 голосов
/ 04 мая 2018

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

Решением будет связать this с _login, например, внутри constructor:

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

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

<Button raised onPress={() => { this._login() }} title="Sign in" />
0 голосов
/ 04 мая 2018

Сначала вы пытаетесь использовать 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 *
}

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

Если это сделано в строке, то функция NEW назначается на onPress, и реакция будет повторно визуализировать эту часть без необходимости.

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

EDIT

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

  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>
  }

}

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

0 голосов
/ 04 мая 2018

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

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

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

 _login = () => {
    this.props.navigation.navigate('Agenda');
    console.log('Logging in');
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...