我有一个表格。
我尝试从不同的功能提交此表格。
为此,我创建了一个ref
。打印时,此引用具有正确的 HTML 节点,并且此节点还具有submit
方法。当调用此提交方法(formNode.submit()
(时,表单已提交,但onSubmit
处理程序永远不会被触发。
为什么?
下面是一个简化的示例,显示了相同的行为。
class Form extends React.Component {
constructor() {
super();
this.form = React.createRef();
}
render() {
return (
<div onClick={() => this.form.submit()}>
Click me!
<form
onSubmit={e => console.log(e)}
ref={f => (this.form = f)}
/>
</div>
);
}
}
https://codesandbox.io/s/vm8pkmony
从 React 17 开始,您必须向事件添加cancelable
和bubbles
属性。否则,接受答案中的解决方案将不起作用。它是由事件委派中的一些更改引起的。
this.form.dispatchEvent(
new Event("submit", { cancelable: true, bubbles: true })
);
对于您的特定用例,您必须使用dispatchEvent
触发表单的submit
事件。
this.form.dispatchEvent(new Event("submit"));
调用窗体的submit
函数时,不会触发submit
事件。
此行为是有意的,因为我们假设如果您直接致电submit
,您已经验证了表单。
这是一个古老的问题,但我们可以做这样的事情;
正如上面提到的拉蒙·巴尔萨扎;
调用表单的提交函数时,提交事件不是 解雇。
为了解决这个问题,我们可以创建隐藏按钮并添加对它的引用,而不是我们可以点击带有 ref 的按钮,它将提交表单并触发提交事件;
import { useRef } from 'react'
export default function Form(props) {
const hiddenButtonRef = useRef(null)
return (
<>
<form onSubmit={(e) => console.log(e)}>
<input type="submit" style={{ display: 'none' }} ref={hiddenButtonRef} />
</form>
<div onClick={() => hiddenButtonRef.current.click()}>Click me!</div>
</>
)
}
更新的解决方案 目前我使用formRef.current.requestSubmit()
const formRef = useRef<HTMLFormElement>(null);
const onClickCheckout = () => {
if (formRef.current) {
formRef.current.scrollIntoView({ block: "nearest", behavior: "smooth" });
formRef.current.requestSubmit();
}
};
`
对于 2021 年使用功能组件的人:
你必须在表单中包含<button>
,并且不需要添加其他道具来触发<form>
的onSubmit
事件!
例如:
<form ref={formRef} onSubmit={handleSubmit}>
<div style={{display: "flex", flexDirection: "column"}}>
<h1 style={{ alignSelf: "center" }}>Import Your Space</h1>
<InputText label="space-id" ref={spaceIdRef}
init={spaceId} onChange={value => setSpaceId(value)}/>
<InputText label="map-id" ref={mapIdRef}
init={mapId} onChange={value => setMapId(value)}/>
<InputTextArea label="rooms" ref={roomsRef}
init={rooms} onChange={value => setRooms(value)}/>
<button style={{background: "lightgreen", alignSelf: "flex-end"}}>
Start Discrimination</button>
</div>
</form>