web-dev-qa-db-ja.com

React.js:プログラムでフォームを送信してもonSubmitイベントがトリガーされない

リンクをクリックした後にReactフォームを送信したい。

そのためには、リンクがクリックされた場合にプログラムでフォームを送信する必要があります。

私の問題は:onSubmitハンドラーがフォーム送信後に起動されないことです。

この目的のために作成したコードは次のとおりです。

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')
);

handleSubmitは呼び出されず、デフォルトの動作(実行中のフォーム)が実行されます。これはReactJsのバグですか、それとも通常の動作ですか? onSubmitハンドラーを呼び出す方法はありますか?

21
Ahmed Kooli

私はこれで成功しています。これにより、クリック時にhandleSubmitがトリガーされます。お役に立てれば。

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

ここから見つかりました: https://github.com/facebook/react/issues/6796

8
Melvin

現在のonSubmitは、native形式ではなく、React SyntheticEvent のトリガーにバインドされていますそれは、this.refs.formToSubmit.submit();がハンドラーをトリガーしない理由を説明します。私が知る限り、そのSyntheticEventを手動でトリガーしようとすることは、推奨または価値のある追求ではありません。

これを実現する慣用的な方法は、JSX/HTMLを構造化して<button>または<input>タイプの送信。どちらもhandleSubmitハンドラーをトリガーします。私の意見では、それは複雑さを軽減し、あなたのハンドラを統合し、あなたの最良の解決策であると思われます。

例えば.

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

これと同じ問題がありましたが、修正できませんでした。 document.querySelector('form').submit()を実行しても、onSubmitハンドラーはトリガーされません。目に見えない_<input type="submit">_を含めてみましたが、それでも.submit()はトリガーしません。そのため、不可視のサブミット(_style="display:none"_)を保持し、その不可視のサブミットボタンで.click()を実行するように変更しました。驚くことに、_display:none_でも動作します。ただし、Firefoxでのみテストしました。

2
Noitidart

デフォルトでは、フォームrefがsubmitに追加のコールバックをアタッチすることを期待すべきではありません。これは、DOM要素refsなどのプログラムで設定されたものを使用する場合、フレームワークの設計が不適切です。

refの未定の内部実装に依存する代わりに、必要なすべてのイベントを任意の順序でインスタンス化するには、refを使用する必要があります[form要素によってインスタンス化される場合]。

これは動作します:

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

実際のsubmitは常に最後に来る必要があります。

2
Denialos

アンカータグは送信イベントをトリガーしないため、アンカータグではなく送信タイプの入力タグを使用する必要があります。

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

これはReactとは関係ありません。これはDOM APIの「機能」です。.submit()メソッドはsubmitイベントを実際に起動せず、入力検証もトリガーしません。 http://codetheory.in/javascript-fire-onsubmit-by-calling-form-submit/ を参照してください。

考えられる回避策は、提案されているように、送信ボタンを作成し、プログラムで.click()を呼び出すことです。または、プログラムでsubmitイベントをnew Event()で作成し、.dispatchEvent()を使用してディスパッチできます。ただし、new Event()はIEでは使用できません。

0
muodov