web-dev-qa-db-fra.com

Réagir: ceci est nul dans le gestionnaire d'événements

J'ai un composant LoginForm. Je veux vérifier avant de soumettre, que loginName et password sont définis. J'ai essayé avec ce code (beaucoup de trucs omis):

class LoginForm extends Component {

  constructor() {
    super();

    this.state = {
      error: "",

      loginName: "",
      password: "",
      remember: true
    };
  }


  submit(e) {
    e.preventDefault();
    if(!this.state.loginName || !this.state.password) { //this is null
      this.setState({ error: "Fill in both fields" });
    } else {
      console.log("submitting form");
    }
  }

  render() {
    return (
      <div className="col-xs-12 col-sm-6 col-md-4">
        <form className="login" onSubmit={this.submit}>
          <button type="submit" className="btn btn-default">Sign in</button>
        </form>
      </div>
    );
  }
}

export default LoginForm;

cependant, j'obtiens un TypeError dans le gestionnaire d'événements, disant que this est nul.

Que dois-je faire?

38
Midiparse

Vous devez définir this pour la méthode submit car maintenant this est undefined, pour cette opération, vous pouvez utiliser .bind

onSubmit={ this.submit.bind(this) }

Example

ou vous pouvez utiliser fonction flèche

onSubmit={ (e) => this.submit(e) }

Example

67
Alexander T.

React vous a déjà lié des rappels. Mais maintenant, il a disparu, et vous devez le lier vous-même ou faire un emballage comme

onSubmit={() => this.submit()}
8
huston007

Pour ceux qui utilisent Babel, vous pouvez utiliser opérateur de liaison avec transform-function-bind plugin:

onSubmit={::this.submit}

qui est un sucre syntaxique pour:

onSubmit={this.submit.bind(this)}
2
Oleg

Vous n'avez pas lié le this à votre classe; Vous pouvez utiliser la fonction de propriétés de classe ES6 pour contourner le problème de la manière la plus propre; Il vous suffit donc de:

   submit = (e) => {
      // some code here
   }

La fonction flèche le liera automatiquement; Bien plus agréable que de le lier dans un constructeur; la chose la plus importante est de ne jamais le faire de cette façon:

onSubmit={() => this.submit()}

Cela va créer une fonction qui est un objet en javascript et cela prendra de la mémoire et réside maintenant dans votre fonction redner! ce qui le rend si cher. La fonction render fait partie du code qui s'exécute tant de fois et chaque fois que votre fonction submit est également créée et vous vous retrouverez avec des problèmes de performances. Votre code devrait donc être comme:

class LoginForm extends Component {
  submit = (e) => {
    // some code here
  }

  render() {
    return (
        <form className="login" onSubmit={ this.submit }>
          <button type="submit" className="btn btn-default">Sign in</button>
        </form>
      );
    }
}

export default LoginForm;

Ici, vous n'aurez pas de problème de performances, vous n'aurez pas non plus de problème de liaison et votre code sera beaucoup plus agréable.

1
Vennesa