web-dev-qa-db-fra.com

React.js: soumettre le formulaire par programme ne déclenche pas l'événement onSubmit

Je souhaite soumettre un formulaire de réaction après un clic sur un lien.

Pour ce faire, je dois soumettre le formulaire par programmation si le lien est cliqué.

mon problème est le suivant: le gestionnaire onSubmit n'est pas renvoyé après l'envoi du formulaire.

Voici un code que j'ai créé à cet effet: 

var MyForm = React.createClass({
  handleSubmit: function(e){
    console.log('Form submited');
     e.preventDefault();
  },
  submitForm : function(e){
    this.refs.formToSubmit.submit();
  },
  render: function() {
    return (
    <form ref="formToSubmit" onSubmit={this.handleSubmit}>
    <input name='myInput'/>
    <a onClick={this.submitForm}>Validate</a>
    </form>);
  }
});

ReactDOM.render(
  <MyForm name="World" />,
  document.getElementById('container')
);

La handleSubmit n'est pas appelée et le comportement par défaut est exécuté (le formulaire soumis) . S'agit-il d'un bogue de ReactJs ou d'un comportement normal? Y a-t-il un moyen d'obtenir le gestionnaire onSubmit appelé?

15
Ahmed Kooli

J'ai du succès avec ça. Cela déclenche le handleSubmit en cliquant sur. J'espère que cela t'aides.

<form onSubmit={this.handleSubmit} ref={el => this.form = el}>
    <a onClick={() => { this.form.dispatch(new Event('submit'))}}>Validate</a>
</form>

Trouvé à partir d'ici: https://github.com/facebook/react/issues/6796

4
Melvin

Votre onSubmit actuelle est liée au déclenchement d'un événement React SyntheticEvent et non du formulaire native. Cela explique pourquoi this.refs.formToSubmit.submit(); ne déclenche pas votre gestionnaire. Autant que je sache, essayer de déclencher manuellement ce SyntheticEvent n'est pas une poursuite recommandée ou valable.

Je pense que la façon idiomatique d’y parvenir est de structurer le fichier JSX/HTML de manière à utiliser un <button> ou un <input> de type submit. Cela déclenchera votre gestionnaire handleSubmit. À mon avis, cela réduira la complexité, consolidera vos gestionnaires et semble être votre meilleure solution.

par exemple.

  • <input type="submit" value="Validate" />
  • <button type="submit">Validate</button>
2
Matt Kahl

J'ai eu le même problème mais je ne pouvais pas le réparer. Quoi que je fasse, faire document.querySelector('form').submit() ne déclenchera pas le gestionnaire onSubmit. J'ai essayé d'inclure un <input type="submit"> invisible, mais toujours .submit() ne le déclencherait pas. Je me suis donc contenté de garder la soumission invisible (style="display:none"), puis de faire .click() sur ce bouton de soumission invisible, cela fonctionne même avec display:none. Je n'ai testé que dans Firefox cependant.

2
Noitidart

Vous ne devez pas vous attendre à ce qu'une référence de formulaire attache un rappel supplémentaire à submit pour vous par défaut. Ce serait une mauvaise conception du cadre lorsque vous travaillez avec des choses définies par programme telles que l'élément DOM refs.

Vous devez utiliser la variable ref pour instancier tous les événements dont vous avez besoin dans l'ordre de votre choix au lieu de vous appuyer sur une implémentation interne indicibles d'une ref [lorsqu'elle est instanciée par un élément form].

Cela marche:

this.refs.formToSubmit.onSubmit();
this.refs.formToSubmit.submit();

La valeur réelle submit devrait toujours apparaître en dernier.

2
Denialos

Vous devriez utiliser une balise d'entrée avec le type submit plutôt que la balise d'ancrage, car la balise d'ancrage ne déclenche pas un événement de soumission.

render: function() {
  return (
    <form ref="formToSubmit" onSubmit={this.handleSubmit}>
       <input name='myInput'/>
       <input onClick={this.submitForm} type="submit" value="Validate" />
    </form>
  );
}
0

Cela n'a rien à voir avec React. C'est une "fonctionnalité" de l'API DOM: la méthode .submit() ne déclenche pas réellement l'événement submit et ne déclenche pas non plus de validation des entrées. Voir http://codetheory.in/javascript-fire-onsubmit-by-calling-form-submit/ .

La solution possible consiste, comme suggéré, à créer un bouton d'envoi et à appeler .click() par programme ..__ ou à créer par programme un événement submit avec new Event() et à le répartir à l'aide de .dispatchEvent(). Cependant, new Event() n'est pas disponible dans IE.

0
muodov