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

IT技术 forms reactjs onsubmit
2021-04-24 11:17:53

我想在点击链接后提交一个 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 处理程序?

4个回答

我在这方面取得了成功。这会在单击时触发 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

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

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

例如

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

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) 中,事件委托发生了巨大的变化(详情请点击此处)。因此,上面的解决方案需要一个小的改进才能使用这个版本的库。这个变化就是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>

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