You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+TS+React-Hook-Form 提交表单同时关闭模态窗失效

问题根因

当前Save按钮的写法存在执行顺序冲突:

  • 按钮同时绑定type="submit"和onClick={onClose}时,点击会先触发onClick事件执行关窗,模态窗组件被父组件卸载后,表单元素直接从DOM树移除,后续的表单submit事件、React-Hook-Form的提交逻辑、Redux dispatch操作都会被中断,导致数据无法正常存入store。
  • 如果把按钮type改为button,按钮本身不会触发表单原生提交事件,且你没有在点击事件中手动调用表单提交方法,自然会出现既不提交数据、也因组件卸载时序问题无法正常关窗的现象。

Cancel、右上角关闭按钮能正常生效,是因为这两个按钮本身不涉及表单提交逻辑,点击后直接执行onClose不会有逻辑冲突。

修复步骤

核心原则:关窗逻辑必须放在表单提交成功的回调内执行,保证数据持久化完成后再关闭模态窗,不要把onClose直接绑在Save按钮的点击事件上。

  1. 调整表单提交回调onSubmit,在dispatch数据成功后调用onClose关窗:
const onSubmit = handleSubmit((data) => {
  dispatch(setList(data));
  onClose(); // 数据提交完成后再执行关窗
});
  1. 移除Save按钮上绑定的onClick={onClose},保留type="submit"属性即可,修改后的按钮代码:
<button className="button1" type="submit" value="submit">Save</button>
多步表单额外适配建议

你当前实现的是3步表单,建议补充两个配置避免后续出现数据丢失问题:

  • 给useForm添加shouldUnregister: false配置,默认情况下React-Hook-Form会在输入框组件卸载时注销对应字段,切页时前几页的输入值会丢失,加上该配置后会保留所有步骤的表单数据:
const { register, handleSubmit, formState: { errors, isValid }} = useForm<UI>({ 
  mode: "all",
  shouldUnregister: false
});
  • 不要用全局的isValid状态控制Next按钮的禁用状态,当前isValid会校验整个表单的所有必填项,第一页加载时因为第二、三页的必填项为空,isValid会一直为false,导致Next按钮无法点击。建议按当前页的字段单独做分步校验。

内容的提问来源于stack exchange,提问作者Sergio D. Gimenez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 05:54:36