使用react-hook form的setError时如何使表单状态变为无效?
React Hook Form 手动设置错误后控制表单提交的解决方案
React Hook Form 的 isValid 字段确实只根据注册时的校验规则或校验schema来计算,手动调用 setError 添加的错误不会自动影响它的状态。要解决这个问题,让自定义组件返回错误时禁用提交按钮,有以下几个可行方案:
方案一:结合 errors 对象与 isValid 控制按钮禁用
直接检查手动设置的错误是否存在,同时结合原有表单的校验状态来判断按钮是否禁用:
import { useForm } from 'react-hook-form'; const YourForm = () => { const { setError, formState: { errors, isValid } } = useForm(); // 判断提交按钮是否禁用:表单校验不通过 或 logo字段存在手动设置的错误 const isSubmitDisabled = !isValid || !!errors.logo; const setLogoError = () => { setError('logo', { type: 'custom', message: 'custom message' }); }; return ( <form> {/* 你的自定义Logo组件,回调触发setLogoError */} <CustomLogoComponent onError={setLogoError} /> <button type="submit" disabled={isSubmitDisabled}>提交</button> </form> ); };
方案二:给字段注册空校验规则,配合 trigger 更新 isValid
先给目标字段注册一个空的校验规则,之后调用 trigger 触发该字段的校验流程,让手动设置的错误被纳入 isValid 的计算:
import { useForm } from 'react-hook-form'; const YourForm = () => { const { register, setError, trigger, formState: { isValid } } = useForm(); // 给logo字段注册一个空校验规则 register('logo', { validate: () => true }); const setLogoError = () => { setError('logo', { type: 'custom', message: 'custom message' }); // 触发logo字段的校验,让isValid重新计算 trigger('logo'); }; return ( <form> <CustomLogoComponent onError={setLogoError} /> <button type="submit" disabled={!isValid}>提交</button> </form> ); };
方案三:自定义状态监听错误变化
通过 useEffect 监听表单的 errors 和 isValid 变化,维护一个自定义的表单有效状态来控制按钮:
import { useState, useEffect } from 'react'; import { useForm } from 'react-hook-form'; const YourForm = () => { const { setError, formState: { errors, isValid } } = useForm(); const [isFormValid, setIsFormValid] = useState(isValid); // 当表单校验状态或错误列表变化时,更新自定义状态 useEffect(() => { // 当原有校验通过且没有手动设置的错误时,表单才有效 setIsFormValid(isValid && Object.keys(errors).length === 0); }, [isValid, errors]); const setLogoError = () => { setError('logo', { type: 'custom', message: 'custom message' }); }; return ( <form> <CustomLogoComponent onError={setLogoError} /> <button type="submit" disabled={!isFormValid}>提交</button> </form> ); };
内容的提问来源于stack exchange,提问作者Shehzadi khushi
相关产品推荐
相关产品推荐

