React Hook Form问题:初始输入不显示错误但isValid始终为false
问题解决思路及修正代码
你的核心问题有两个:
- 自定义
onChange覆盖了react-hook-form内置的输入同步逻辑,导致表单从未正确获取输入值,所以isValid始终为false - 代码里的
register配置项缺少逗号,属于语法错误
下面是修正后的完整代码,同时优化了错误判断逻辑:
const MyForm = () => { const formMethods = useForm({ mode: 'onChange' }) const { register, formState: { errors } } = formMethods const [minCharLimitMet, setMinCharLimitMet] = useState(false) const onChangeCustom = (e) => { if (!minCharLimitMet && e.target.value.length > 10) { setMinCharLimitMet(true) } } return ( <FormProvider {...formMethods}> <form noValidate onSubmit={(e) => { e.preventDefault(); // 这里添加你的提交逻辑 }}> <input type="text" {...register('inputName', { // 组合内置逻辑与自定义逻辑,不直接覆盖onChange onChange: (e) => { onChangeCustom(e); // 调用react-hook-form默认onChange同步表单状态 register('inputName').onChange(e); }, required: true, minLength: { value: 10, message: '内容长度不能少于10字符' }, maxLength: { value: 100, message: '内容长度不能超过100字符' } })} /> {/* 仅在用户越过10字符阈值后,且当前输入不符合规则时显示错误 */} {minCharLimitMet && errors.inputName && <span>{errors.inputName.message}</span>} </form> </FormProvider> ) }
关键改动说明
- 恢复表单状态同步:自定义
onChange时先执行自己的阈值判断逻辑,再调用react-hook-form内置的onChange,确保表单能正确获取输入值,errors和isValid才会正常更新。 - 修正语法错误:给
register配置里的required、minLength等项补上逗号,避免JS语法报错。 - 精准错误判断:改用
errors.inputName判断当前字段的错误,结合minCharLimitMet控制错误显示时机,比全局isValid更精准(全局isValid会受整个表单所有字段的影响)。 - 优化错误提示:给
minLength和maxLength配置了自定义错误消息,提升用户体验。
如果你觉得自定义onChange太繁琐,也可以用watch简化阈值判断逻辑,不需要额外的useState:
const MyForm = () => { const formMethods = useForm({ mode: 'onChange' }) const { register, formState: { errors }, watch } = formMethods // 监听输入框值,初始为空字符串 const inputValue = watch('inputName', '') const [minCharLimitMet, setMinCharLimitMet] = useState(false) useEffect(() => { // 只要输入长度超过10,就标记阈值已越过 if (inputValue.length > 10) { setMinCharLimitMet(true) } }, [inputValue]) return ( <FormProvider {...formMethods}> <form noValidate onSubmit={(e) => { e.preventDefault(); }}> <input type="text" {...register('inputName', { required: true, minLength: { value: 10, message: '内容长度不能少于10字符' }, maxLength: { value: 100, message: '内容长度不能超过100字符' } })} /> {minCharLimitMet && errors.inputName && <span>{errors.inputName.message}</span>} </form> </FormProvider> ) }
这个版本用watch监听输入值,通过useEffect自动更新阈值状态,代码更简洁直观。
内容的提问来源于stack exchange,提问作者noblerare
相关产品推荐
相关产品推荐

