未触发提交处理程序的 React Ref Form onSubmit Handler



我有一个表格。

我尝试从不同的功能提交此表格。

为此,我创建了一个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 开始,您必须向事件添加cancelablebubbles属性。否则,接受答案中的解决方案将不起作用。它是由事件委派中的一些更改引起的。

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>

最新更新