I want to submit a React form after a click on a link.
To do so I need to submit the form programmatically if the link is clicked.
my problem is : onSubmit
handler is not being fired after the form submit .
Here is a code snipped that I made for this purpose:
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')
);
The handleSubmit
is not invoked and the default behavior is executed (the form being submitted).
Is this a ReactJs bug or a normal behavior?
Is there a way to get the onSubmit handler invoked ?
答案 0 :(得分:6)
我成功了。单击后触发handleSubmit。希望这会有所帮助。
<form onSubmit={this.handleSubmit} ref={el => this.form = el}>
<a onClick={() => { this.form.dispatch(new Event('submit'))}}>Validate</a>
</form>
答案 1 :(得分: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>
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>
答案 2 :(得分:4)
您当前的onSubmit
必然会触发React SyntheticEvent,而不会触发原生表单提交事件。这解释了为什么this.refs.formToSubmit.submit();
没有触发你的处理程序。据我所知,试图手动触发SyntheticEvent不是推荐或值得追求的。
我认为实现此目的的惯用方法是将JSX / HTML结构化为使用提交类型<button>
或<input>
。其中任何一个都会触发您的handleSubmit
处理程序。在我看来,它将降低复杂性,巩固您的处理程序,并且似乎是您最好的解决方案。
e.g。
<input type="submit" value="Validate" />
<button type="submit">Validate</button>
答案 3 :(得分:2)
我遇到了同样的问题,但无法修复。无论我做了什么,执行document.querySelector('form').submit()
都不会触发onSubmit
处理程序。我尝试包含一个不可见的<input type="submit">
,但仍然.submit()
不会触发它。所以我只是更改为保持隐形提交(style="display:none"
),然后对该隐形提交按钮执行.click()
,令人惊讶的是它甚至可以与display:none
一起使用。我只在Firefox中测试过。
答案 4 :(得分:2)
默认情况下,您不应期望表单引用为submit
添加额外的回调。当使用编程方式设置DOM元素refs
等内容时,这将是框架的糟糕设计。
您应该使用ref
以您想要的任何顺序实例化所需的所有事件,而不是依赖于ref
的无法实现的内部实现[由form
实例化时元素]。
这有效:
this.refs.formToSubmit.onSubmit();
this.refs.formToSubmit.submit();
实际submit
应始终排在最后。
答案 5 :(得分:0)
您应该使用带有提交类型的输入标记而不是锚标记,因为锚标记不会触发提交事件。
main
答案 6 :(得分:0)
这与React无关。这是DOM API的“功能”:.submit()
方法实际上不会触发submit
事件,它也不会触发输入验证。参见http://codetheory.in/javascript-fire-onsubmit-by-calling-form-submit/。
根据建议,可能的解决方法是创建一个提交按钮,并以编程方式在其上调用.click()
。
或者,您可以使用submit
以编程方式创建new Event()
事件,并使用.dispatchEvent()
进行调度。但是,new Event()
在IE中不可用。
答案 7 :(得分:0)
您宁愿使用dispatchEvent(new Event('submit'))
而不是submit()
。只需相应地更换即可。