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

如何在表单验证失败时阻止shadcn/ui的Sheet组件关闭

shadcn/ui Sheet表单验证失败时阻止关闭的解决方案

问题背景

使用shadcn/ui的Sheet组件内嵌表单时,点击提交按钮后即便表单验证失败,Sheet仍会自动关闭,需要重新打开修正错误。现有代码中提交按钮被SheetClose包裹,导致无论验证结果如何都会触发Sheet关闭;尝试添加aria-errormessage、onError等属性无效。

原代码结构:

<Sheet>
  <SheetTrigger asChild>...</SheetTrigger>
  <SheetContent>
    <div className="grid gap-4 py-4">
      <Form { ...form }>
         <form onSubmit={ form.handleSubmit(onSubmit) } className="w-full space-y-6">
           ...
           <SheetFooter>
             <SheetClose asChild>
               <Button type="submit">Save changes</Button>
             </SheetClose>
           </SheetFooter>
         </form>
       </Form>
    </div>
  </SheetContent>
</Sheet>

解决方法

方法1:通过Sheet状态手动控制关闭(推荐)

核心是取消SheetClose对提交按钮的包裹,仅在表单验证通过后手动调用关闭方法。

  1. 引入并使用useDisclosure钩子管理Sheet状态:
import { useDisclosure } from '@/components/ui/use-disclosure';

const { open, onOpen, onClose } = useDisclosure();
  1. 修改Sheet绑定状态,并调整提交逻辑:
<Sheet open={open} onOpenChange={(newState) => {
  // 可选:处理状态变化逻辑
}}>
  <SheetTrigger asChild>...</SheetTrigger>
  <SheetContent>
    <div className="grid gap-4 py-4">
      <Form { ...form }>
         <form 
           onSubmit={ form.handleSubmit((validatedData) => {
             // 验证通过后执行提交逻辑
             onSubmit(validatedData);
             // 手动关闭Sheet
             onClose();
           }) } 
           className="w-full space-y-6"
         >
           {/* 表单字段 */}
           ...
           <SheetFooter>
             {/* 直接使用提交按钮,不包裹SheetClose */}
             <Button type="submit">Save changes</Button>
             {/* 单独保留取消按钮用SheetClose */}
             <SheetClose asChild>
               <Button variant="secondary">Cancel</Button>
             </SheetClose>
           </SheetFooter>
         </form>
       </Form>
    </div>
  </SheetContent>
</Sheet>

form.handleSubmit只会在验证通过时执行回调,此时才会调用onClose()关闭Sheet;验证失败时回调不触发,Sheet保持打开。

方法2:阻止SheetClose的默认行为(备选)

如果不想大幅修改结构,可在SheetClose上添加点击事件,检查表单错误后阻止关闭:

<SheetFooter>
  <SheetClose 
    asChild
    onClick={(e) => {
      // 检查表单是否存在验证错误
      if (Object.keys(form.formState.errors).length > 0) {
        e.preventDefault();
        e.stopPropagation();
      }
    }}
  >
    <Button type="submit">Save changes</Button>
  </SheetClose>
</SheetFooter>

注意:需确保表单开启了实时验证,否则点击按钮时可能还未生成错误状态,导致判断失效。

内容的提问来源于stack exchange,提问作者Sounak Mandal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 05:22:44