J'ai créé une simple page de connexion qui, une fois le bouton enfoncé, exécute cette fonction:

login = (email, password, navigate) => {
  this.setState({ loginButtonPressed: true });
  firebase
    .auth()
    .signInWithEmailAndPassword(email, password)
    .then(function(user) {
      navigate('Profile');
    })
    .catch(function(error) {
      this.setState({ loginButtonPressed: false });
      Alert.alert(error.toString());
    });
};

Une fois appelé, il exécute "this.setState ({loginButtonPressed: true})" puisque le bouton change de forme (il est marqué comme pressé). Mais j'obtiens l'erreur suivante: Undefined n'est pas une fonction this.setState .

Comment résoudre ce problème? Merci de votre aide.

2
Jean 13 avril 2018 à 19:42

5 réponses

Meilleure réponse

Le problème est avec:

.catch(function(error) {
  this.setState({ loginButtonPressed: false });
  Alert.alert(error.toString());
});

Vous créez une fonction anonyme où this référencera cette fonction anonyme (objet), pas un objet React.

Je vois que vous pouvez utiliser les fonctions fléchées, alors corrigez-le comme:

.catch((error) => {
  this.setState({ loginButtonPressed: false });
  Alert.alert(error.toString());
});

Avec la fonction flèche this fera référence au contexte dans lequel il est utilisé.

5
Tomasz Mularczyk 13 avril 2018 à 16:46

Étendez-vous le composant React?

Si vous ne l'êtes pas, vous devrez le faire pour utiliser setState, si vous l'êtes, vous devrez vous assurer de créer l'état dans un constructeur avant de le mettre à jour avec setState ailleurs.

Quelque chose dans le sens de:

class Login extends React.Component {
  constructor(props) {
    super(props);
    this.state = { loginButtonPressed: false };
    this.login = this.login.bind(this);
  }

  login(email, password, navigate) {
    this.setState({ loginButtonPressed: true });
    firebase
      .auth()
      .signInWithEmailAndPassword(email, password)
      .then(function(user) {
        navigate('Profile');
      })
      .catch(function(error) {
        this.setState({ loginButtonPressed: false });
        Alert.alert(error.toString());
      });
  };

  render() {
    return (
      <Button onClick={this.logIn}>Login</Button>
    );
  }
}
0
Seth McClaine 13 avril 2018 à 16:52

Ou vous pouvez conserver une copie de la référence à ceci, comme ceci:

Const self = this; (première ligne de votre fonction);

Et utilisez "self" au lieu de "this" n'importe où dans la fonction.

Vous pouvez l'utiliser dans des endroits où vous ne pourrez peut-être pas utiliser les fonctions fléchées.

1
Ralph 13 avril 2018 à 21:22

Une fonction flèche se souvient de sa portée lexicale. Reportez-vous à la documentation MDN - "Une fonction flèche ne définit pas nouvellement son propre" ceci "lorsqu'elle est exécutée dans le contexte global; à la place, la valeur" this "du contexte lexical englobant est utilisée, ce qui équivaut à la traiter comme une valeur de fermeture. Ainsi, dans le code suivant, le 'this' dans la fonction qui est passée à setInterval a la même valeur que 'this' dans la fonction englobante: "function Person () {this.age = 0;

  setInterval(() => {
    this.age++; // |this| properly refers to the person object
  }, 1000);
}

var p = new Person();
0
Kunal 13 avril 2018 à 16:59

Vous devez bind à this pour avoir accès à l'intérieur du rappel. Essayez-le avec les fonctions fléchées.

0
iceveda06 13 avril 2018 à 16:47