Next14项目中Shadcn Form组件提交功能失效问题排查
问题诊断与修复方案
可能的原因1:表单标签嵌套冲突
你的代码同时使用了Shadcn封装的<Form {...form}>组件和原生<form>标签,双重表单嵌套会导致react-hook-form的提交事件绑定失效,handleSubmit无法正确触发onSubmit函数。Shadcn的Form组件已经内置了原生form元素,无需额外嵌套。
可能的原因2:Zod校验未通过
如果MinistrySchema中存在未满足的校验规则(比如必填字段未填写、格式不符合要求),react-hook-form会自动拦截提交,且默认不会抛出错误提示,直接跳过onSubmit执行。比如你代码里的team、gallery字段在defaultValues中是空数组,但如果Schema要求非空,或者phone字段格式校验不通过,都会导致提交被拦截。
修复步骤
1. 移除多余的原生form标签
将嵌套的表单结构合并,直接通过Shadcn的Form组件绑定提交事件:
// 替换原有的嵌套结构 <Form {...form} onSubmit={form.handleSubmit(onSubmit)} className="flex w-full flex-col gap-10"> {/* 所有FormField和Button直接放在这里 */} </Form>
2. 排查并调整Zod校验规则
- 检查
MinistrySchema的定义,确保所有必填字段都有对应的表单输入组件(比如你代码里未实现chiefPhoto、team、gallery的输入,如果Schema标记这些字段为必填,会直接导致校验失败) - 临时关闭校验进行测试,确认提交逻辑是否正常:
const form = useForm<z.infer<typeof MinistrySchema>>({ // 临时注释resolver,跳过校验 // resolver: zodResolver(MinistrySchema), defaultValues: { /* ... */ }, });
3. 添加调试代码查看校验状态
在组件内部加入调试代码,直接定位校验失败的字段:
// 组件内部添加 console.log("表单错误信息:", form.formState.errors); console.log("表单是否合法:", form.formState.isValid);
4. 移除按钮上的冗余onClick事件
提交逻辑应由form.handleSubmit统一处理,按钮上的onClick属于冗余代码,可直接移除:
<Button type="submit" className="primary-gradient z-50 w-fit !text-light-900" disabled={isSubmitting} > {isSubmitting ? ( <>{type === "edit" ? "Editing..." : "Posting..."}</> ) : ( <>{type === "edit" ? "Edit Question" : "Ask a Question"}</> )} </Button>
修复后核心代码示例
// 渲染部分核心代码 return ( <Form {...form} onSubmit={form.handleSubmit(onSubmit)} className="flex w-full flex-col gap-10"> <FormField control={form.control} name="title" render={({ field }) => ( <FormItem className="flex w-full flex-col"> <FormLabel className="paragraph-semibold text-dark400_light800"> 标题 <span className="text-primary-500">*</span> </FormLabel> <FormControl className="mt-3.5"> <Input className="no-focus paragraph-regular background-light900_dark300 light-border-2 text-dark300_light700 min-h-[56px] border" {...field} /> </FormControl> <FormDescription className="body-regular mt-2.5 text-light-500"> 请简洁明了地填写标题 </FormDescription> <FormMessage className="text-red-500" /> </FormItem> )} /> {/* 其他FormField组件... */} <Button type="submit" className="primary-gradient z-50 w-fit !text-light-900" disabled={isSubmitting} > {isSubmitting ? ( <>{type === "edit" ? "编辑中..." : "提交中..."}</> ) : ( <>{type === "edit" ? "编辑内容" : "提交内容"}</> )} </Button> </Form> );
内容的提问来源于stack exchange,提问作者chekirko
相关产品推荐
相关产品推荐

