React.js: 以编程方式提交表单不会触发 onSubmit 事件

React.js: submit form programmatically does not trigger onSubmit event

我想在点击 link 后提交 React 表单。

为此,如果单击 link,我需要以编程方式提交表单。

我的问题是: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 处理程序?

您应该使用提交类型的输入标签而不是锚标签,因为锚标签不会触发提交事件。

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

我遇到了同样的问题,但无法解决。无论我做什么,document.querySelector('form').submit() 都不会触发 onSubmit 处理程序。我尝试包括一个不可见的 <input type="submit">,但 .submit() 仍然不会触发它。所以我只是更改为保留不可见的提交 (style="display:none"),然后在那个不可见的提交按钮上执行 .click(),令人惊讶的是它甚至可以使用 display:none。不过我只在 Firefox 中测试过。

您当前的 onSubmit 绑定到 React SyntheticEvent 的触发,而不是 native 表单提交事件。这解释了为什么 this.refs.formToSubmit.submit(); 没有触发您的处理程序。据我所知,尝试手动触发 SyntheticEvent 是不推荐或不值得追求的。

我相信实现此目的的惯用方法是构建 JSX/HTML 以使用提交类型的 <button><input>。其中任何一个都会触发您的 handleSubmit 处理程序。在我看来,它将降低复杂性,整合您的处理程序,并且似乎是您的最佳解决方案。

例如

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

默认情况下,您不应期望表单引用会为您附加附加回调 submit。当以编程方式设置诸如 DOM 元素 refs.

之类的东西时,这将是糟糕的框架设计

您应该使用 ref 以您想要的任何顺序实例化您需要的所有事件,而不是依赖 ref [当实例化为 [=15] =]元素].

这个有效:

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

实际 submit 应该总是最后出现。

我成功了。这会在单击时触发 handleSubmit。希望这有帮助。

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

从这里找到:https://github.com/facebook/react/issues/6796

这与 React 无关。它是 DOM API 的 "feature":.submit() 方法实际上不会触发 submit 事件,它也不会触发输入验证。参见 http://codetheory.in/javascript-fire-onsubmit-by-calling-form-submit/

可能的解决方法是,按照建议,创建一个提交按钮,然后以编程方式对其调用 .click()。 或者,您可以使用 new Event() 以编程方式创建一个 submit 事件并使用 .dispatchEvent() 调度它。但是,new Event() 在 IE 中不可用。

您更愿意使用 dispatchEvent(new Event('submit')) 而不是 submit()。对应替换即可。

2021 年更新

已接受答案的解决方案对我不起作用,因此我决定更新此主题。

React 16(及以上)

原答案中缺少Event构造函数的第二个参数。没有{cancelable: true}参数,preventDefault()方法不能运行.

<div>
    <form onSubmit={e => e.preventDefault()} ref={ref => this.form = ref}>
        <input name="tmp" />
    </form>

    <button onClick={e => this.form.dispatchEvent(
        new Event("submit", { cancelable: true })
    )}>
        Submit form
    </button>
</div>

React 17(将来可能会有更新的版本)

在当前版本的React(17)中,事件委托发生了相当大的变化(详情here)。因此,上述解决方案需要稍作改进才能与该版本的库一起使用。此更改是 bubbles: true 参数。工作代码如下所示:

<div>
    <form onSubmit={e => e.preventDefault()} ref={ref => this.form = ref}>
        <input name="tmp" />
    </form>

    <button onClick={e => this.form.dispatchEvent(
        new Event("submit", { cancelable: true, bubbles: true })
    )}>
        Submit form
    </button>
</div>