Next.js 14中React Hook Form+Zod的onSubmit函数无法触发求助
问题分析与解决方案
你的登录表单校验通过后无法进入onSubmit函数,核心原因大概率是**rememberMe复选框的React Hook Form绑定不正确**——你使用的是shadcn/ui封装的Checkbox组件,直接用register无法正确关联到内部的input元素,导致表单始终处于未通过校验的状态(表面无错误提示),从而阻止了onSubmit执行。
以下是具体修复步骤:
1. 修复Checkbox的绑定方式
shadcn/ui的Checkbox是封装组件,需要通过React Hook Form的Controller完成绑定,或手动处理checked和onChange事件:
方法一:使用Controller组件
首先在useForm中解构出control,再用Controller包裹Checkbox:
// 更新useForm解构,添加control和默认值 const { register, handleSubmit, control, // 新增 formState : { errors, isSubmitting } } = useForm<LoginFields>({ resolver: zodResolver(Schema), defaultValues: { // 新增默认值,避免字段未定义 rememberMe: false } }) // 替换原Checkbox代码 <div className="flex items-end gap-2"> <Controller name="rememberMe" control={control} render={({ field }) => ( <Checkbox id="remember" checked={field.value} onCheckedChange={field.onChange} /> )} /> <Label htmlFor="remember">Remember me</Label> </div>
方法二:手动绑定状态
若不想使用Controller,可通过watch监听字段值并手动绑定:
// 更新useForm解构,添加watch const { register, handleSubmit, formState : { errors, isSubmitting }, watch // 新增 } = useForm<LoginFields>({ resolver: zodResolver(Schema), defaultValues: { rememberMe: false } }) const rememberMe = watch('rememberMe'); // 监听rememberMe的值 // 替换原Checkbox代码 <div className="flex items-end gap-2"> <Checkbox id="remember" checked={rememberMe} onCheckedChange={(checked) => register('rememberMe').onChange(checked)} /> <Label htmlFor="remember">Remember me</Label> </div>
2. 排查其他潜在问题
- 移除Input自定义属性:你的Input使用了
showPasswordToggle={true},shadcn/ui原生Input无此属性,若为自定义封装组件,检查是否存在阻止表单提交的逻辑,可暂时移除该属性测试。 - 验证表单有效性:在组件中打印
isValid状态,确认表单是否真的通过校验:const { formState: { isValid } } = useForm(/* ... */); console.log('表单是否有效:', isValid); - 核对依赖版本:确保
react-hook-form、@hookform/resolvers和zod版本兼容,Next.js 14建议使用最新稳定版。
内容的提问来源于stack exchange,提问作者S.M
相关产品推荐
相关产品推荐

