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

Ahm*_*oli 22 forms onsubmit reactjs

我想在点击链接后提交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')
);
Run Code Online (Sandbox Code Playgroud)

handleSubmit不调用并执行默认行为(提交表格).这是一个ReactJs错误还是正常行为?有没有办法调用onSubmit处理程序?

Mel*_*vin 9

我已经成功了。单击后触发handleSubmit。希望这可以帮助。

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

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

  • 如果以上对任何人都不起作用,那么试试这个 - ReactDOM.findDOMNode(this.form).dispatchEvent(new Event("submit")); 并从 'react-dom' 导入 ReactDOM; (2认同)
  • 经过一番摆弄和阅读 github 线程后,我发现有必要使用 `new Event('submit', { cancelable: true })`。这现在在 chrome 和 firefox 上对我有用 (2认同)
  • 当且仅当我们在表单中放置一个提交按钮时,这才有效。我们可以稍后隐藏该提交按钮。我将这个隐藏的提交按钮称为虚拟按钮。例如,在某些情况下,我们在表单之外、页眉、页脚或工具栏中有实际的提交按钮。在所有这些情况下,我们需要在表单中放置一个虚拟提交按钮,否则表单将不会触发任何提交事件。https://github.com/facebook/react/issues/6796#issuecomment-490013451 (2认同)

Noi*_*art 6

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

  • 这是一个黑客,但它有效(在 Chrome 上测试)。用 react 触发隐藏按钮: this.refs.submitHiddenButton.click(); (2认同)

Mat*_*ahl 5

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

我相信完成此操作的惯用方法是构造JSX / HTML以使用<button><input>类型的Submit 。这些都会触发您的handleSubmit处理程序。我认为,这将降低复杂性,巩固您的处理程序,并且似乎是您的最佳解决方案。

例如

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

  • 只是为了向未来的观众阐明这一点: Do `&lt;button type="submit" ref={node =&gt; { this.submitButtonRefOrWhateverYouWannaCallIt = node; }}&gt;验证&lt;/button&gt;`,然后在处理程序中:`this.submitButtonRefOrWhateverYouWannaCallIt.click();` (3认同)
  • 这是我对 React 的主要抱怨之一。它强制执行严格且天真的不切实际的惯用结构。当然,如果您只是提交联系方式或注册表单,那么单击按钮即可完成此操作。但是,例如,更复杂的应用程序可能会在输入模糊或选择选项时自动保存复杂的表单,并且 Redux 和 React 似乎配合得很好,可以防止您在没有巧妙的解决方法的情况下完成此任务。 (2认同)

小智 5

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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)