You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用React Hook Form和Yup实现表单字段动态禁用的问题求助

问题根因

你之前的实现方案存在两个核心问题:

  1. React Hook Form 默认校验触发模式为onSubmit,仅在表单提交时才会生成错误信息写入errors对象;未触发提交/未操作过字段时,空值的错误不会出现在errors中,导致判断失效。
  2. isValid是全局表单校验的异步方法,仅返回全表校验结果,不会主动触发状态重渲染。

可行解决方案

方案一:单字段实时校验(推荐,实现最简单)

  1. 初始化useForm时开启全局实时校验模式mode: "onChange",字段值变动时自动触发校验:
import { useForm } from "react-hook-form";

const { register, formState, getFieldState } = useForm({
  mode: "onChange", // 值变动即触发校验
  defaultValues: {
    name: "", // 字段A的默认值
    fieldB: "" // 字段B的默认值
  }
});
  1. 字段A注册时按业务要求加上校验规则(比如必填、长度限制等):
{/* 字段A */}
<input 
  {...register("name", {
    required: "字段A不能为空",
    minLength: { value: 2, message: "最少输入2位" }
  })}
/>
  1. 字段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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 05:09:00