使用React Hook Form和Yup实现表单字段动态禁用的问题求助
问题根因
你之前的实现方案存在两个核心问题:
- React Hook Form 默认校验触发模式为
onSubmit,仅在表单提交时才会生成错误信息写入errors对象;未触发提交/未操作过字段时,空值的错误不会出现在errors中,导致判断失效。 isValid是全局表单校验的异步方法,仅返回全表校验结果,不会主动触发状态重渲染。
可行解决方案
方案一:单字段实时校验(推荐,实现最简单)
- 初始化
useForm时开启全局实时校验模式mode: "onChange",字段值变动时自动触发校验:
import { useForm } from "react-hook-form"; const { register, formState, getFieldState } = useForm({ mode: "onChange", // 值变动即触发校验 defaultValues: { name: "", // 字段A的默认值 fieldB: "" // 字段B的默认值 } });
- 字段A注册时按业务要求加上校验规则(比如必填、长度限制等):
{/* 字段A */} <input {...register("name", { required: "字段A不能为空", minLength: { value: 2, message: "最少输入2位" } })} />
- 字段B的
disabled属性直接通过getFieldState获取字段A的实时校验状态判断:
{/* 字段B */} <input {...register("fieldB")} disabled={getFieldState("name").invalid} />
getFieldState("字段名").invalid会返回该字段是否不符合校验规则,包含空值、格式错误等所有不通过的场景,不需要依赖errors对象的存在。
方案二:手动监听触发校验(适合不想开启全局实时校验的场景)
如果你不希望全局开启onChange模式消耗性能,可以单独监听字段A的变化,手动触发校验更新状态:
import { useForm, useState, useEffect } from "react"; const { register, trigger, watch } = useForm({ defaultValues: { name: "", fieldB: "" } }); // 监听字段A的实时值 const nameValue = watch("name"); // 存储字段A的校验状态 const [isNameValid, setIsNameValid] = useState(false); // 字段A值变动时手动触发校验 useEffect(() => { const validateName = async () => { const valid = await trigger("name"); setIsNameValid(valid); }; validateName(); }, [nameValue, trigger]);
字段B的禁用逻辑直接使用这个状态即可:
<input {...register("fieldB")} disabled={!isNameValid} />
内容的提问来源于stack exchange,提问作者jjlittle
相关产品推荐
相关产品推荐

