React Hook Form中登录按钮点击后handleLogin函数未触发求助
问题原因
- 事件绑定冲突:你给提交按钮加了
onClick,同时又在<form>上用了react-hook-form的handleSubmit,这完全是多此一举。注册按钮能正常执行,其实是因为handleFormSubmit里本来就会调用handleRegister,跟按钮的onClick没关系。 - 表单验证不兼容:你的
formSchema大概率没区分登录/注册模式,登录时还在要求填写email、confirmPassword这类注册专属字段,导致表单验证失败,handleSubmit直接跳过了handleFormSubmit的执行,自然handleLogin不会触发。
修复方案
第一步:删掉按钮上的onClick
react-hook-form的提交逻辑完全由<form>的onSubmit接管,按钮只需要保留type="submit"就行:
{showRegister ? ( <button type="submit">Register</button> ) : ( <button type="submit">Login</button> )}
第二步:动态生成验证规则
根据showRegister的状态,分别生成登录和注册对应的验证schema,避免登录时校验不必要的字段:
import { useMemo } from 'react'; import { z } from 'zod'; // ...其他代码 // 用useMemo根据状态动态生成schema const formSchema = useMemo(() => { // 登录必填字段的基础验证 const baseSchema = z.object({ username: z.string().min(1, '用户名不能为空'), password: z.string().min(6, '密码至少要6位'), }); // 注册模式下扩展字段和额外验证 if (showRegister) { return baseSchema.extend({ confirmPassword: z.string().min(6, '确认密码至少6位'), email: z.string().email('请输入有效的邮箱'), }).refine(data => data.password === data.confirmPassword, { message: '两次输入的密码不一致', path: ['confirmPassword'], }); } return baseSchema; }, [showRegister]); // 初始化useForm时传入动态生成的schema const { register, handleSubmit, formState: { errors }, reset, } = useForm<FormSchemaType>({ resolver: zodResolver(formSchema), });
第三步:检查输入字段的注册
确保所有输入框都正确调用了register绑定到对应的字段,比如:
// 用户名输入框 <input type="text" {...register('username')} placeholder="用户名" /> {errors.username && <span style={{color: 'red'}}>{errors.username.message}</span>} // 密码输入框 <input type="password" {...register('password')} placeholder="密码" /> {errors.password && <span style={{color: 'red'}}>{errors.password.message}</span>} // 注册模式下才显示的字段 {showRegister && ( <> <input type="password" {...register('confirmPassword')} placeholder="确认密码" /> {errors.confirmPassword && <span style={{color: 'red'}}>{errors.confirmPassword.message}</span>} <input type="email" {...register('email')} placeholder="邮箱" /> {errors.email && <span style={{color: 'red'}}>{errors.email.message}</span>} </> )}
第四步:调试验证错误
如果还是有问题,可以在页面上打印errors对象,看看哪个字段验证失败了:
<pre>{JSON.stringify(errors, null, 2)}</pre>
这样调整后,登录时只要表单验证通过,就会正常触发handleFormSubmit,进而调用handleLogin,调试用的console.log也能正常输出了。
内容的提问来源于stack exchange,提问作者Hemant Khatiwada
相关产品推荐
相关产品推荐

