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>
这与 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>
我想在点击 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>
这与 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>