React Hook Form提交验证:如何等待错误状态更新?
解决React Hook Form提交时验证状态未及时更新的问题
核心原因
你遇到的问题本质是validate/trigger属于异步操作,调用后立即读取formState.errors时,状态还未完成更新,导致拿到空对象。下面是几种直接有效的解决方式:
方案1:用handleSubmit自带的验证流程(推荐)
React Hook Form的handleSubmit会自动先执行所有验证(字段级+提交时自定义验证),只有验证完全通过才会进入你的提交逻辑,无需手动调用validate或读取errors。
示例代码:
import { useForm } from 'react-hook-form'; function YourModalForm() { const { register, handleSubmit, formState: { errors }, setError } = useForm(); const onValidSubmit = async (formData) => { // 这里的formData已经是验证通过后的合法数据 // 执行你的mutation逻辑 await yourApiMutation(formData); // 关闭模态框 closeModal(); }; // 如果需要额外的提交时自定义验证(比如异步校验) const onSubmit = async (formData) => { // 示例:异步检查用户名是否重复 const isDuplicate = await checkUsernameUnique(formData.username); if (isDuplicate) { setError('username', { message: '该用户名已存在' }); return; // 终止后续提交流程 } // 验证通过,执行提交 await onValidSubmit(formData); }; return ( <form onSubmit={handleSubmit(onSubmit)}> <input {...register('username', { required: '用户名不能为空' })} placeholder="用户名" /> {errors.username && <span className="error">{errors.username.message}</span>} <button type="submit">保存</button> </form> ); }
方案2:手动调用trigger并等待异步结果
如果必须手动触发验证而非用handleSubmit,可以使用trigger方法——它会返回一个布尔值表示验证是否通过,同时会更新errors状态,必须等待这个Promise完成后再判断。
示例代码:
import { useForm } from 'react-hook-form'; function YourModalForm() { const { register, trigger, formState: { errors } } = useForm(); const onSave = async () => { // 触发所有字段的验证,等待异步操作完成 const isAllValid = await trigger(); // 此时errors已更新,可直接判断 if (isAllValid && Object.keys(errors).length === 0) { const formData = getValues(); // 获取表单数据 await yourApiMutation(formData); closeModal(); } }; return ( <div> <input {...register('email', { required: '邮箱不能为空', pattern: { value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: '邮箱格式不正确' } })} /> {errors.email && <span className="error">{errors.email.message}</span>} <button onClick={onSave}>保存</button> </div> ); }
trigger也可以单独验证某个字段,比如trigger('email')只校验邮箱字段。
方案3:监听errors状态变化(特殊场景用)
如果因为业务逻辑限制必须依赖errors状态变化,可以用useEffect监听,但这种方式不如前两种直接,仅作备选:
import { useForm } from 'react-hook-form'; import { useEffect, useRef } from 'react'; function YourModalForm() { const { register, trigger, formState: { errors } } = useForm(); const isSubmitting = useRef(false); // 标记是否正在提交 const onSave = () => { isSubmitting.current = true; trigger(); // 触发验证 }; useEffect(() => { if (isSubmitting.current) { isSubmitting.current = false; // 验证通过则执行提交 if (Object.keys(errors).length === 0) { const formData = getValues(); yourApiMutation(formData).then(() => closeModal()); } } }, [errors]); // 表单渲染逻辑... }
内容的提问来源于stack exchange,提问作者Leff
相关产品推荐
相关产品推荐

