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

如何在React Hook Form v6的Controller中使用Yup校验实现onTouched触发报错

问题原因

你当前的错误只在提交时显示,核心是两个问题:

  1. 没有给输入组件绑定onBlur事件,React Hook Form 的touched状态完全依赖onBlur触发,没有这个事件的话,RHF 不知道字段是否被用户聚焦过,onTouched模式的校验规则自然不会触发,只有提交时 RHF 会强制把所有字段标记为 touched 才会展示错误。
  2. 错误提示没有结合touched状态判断,不符合你要的「失焦后才展示错误」的交互逻辑。

修正方案

直接修改封装的子组件Controller部分的代码即可:

// 修正后的Children组件
<Controller
    control={control}
    name={name}
    defaultValue=""
    // 取出onBlur方法和字段状态
    render={({ field: { onChange, value, name, onBlur }, fieldState: { touched } }) => (
        <>
            <NumberFormat
                className="form-control form-control-lg"
                type="text"
                format={format}
                id={name}
                value={value}
                onChange={onChange}
                // 绑定onBlur事件,触发touched状态更新
                onBlur={onBlur}
            />
            {/* 只有字段被失焦过且存在错误时,才展示提示 */}
            {touched && errors && <span className="text-danger">{errors.message}</span>}
        </>
    )}
/>

如果你不想从父组件传递errors参数,也可以直接用Controller返回的fieldState里的error,写法更简洁:

// 不需要父组件传errors的版本
<Controller
    control={control}
    name={name}
    defaultValue=""
    render={({ field: { onChange, value, name, onBlur }, fieldState: { touched, error } }) => (
        <>
            <NumberFormat
                className="form-control form-control-lg"
                type="text"
                format={format}
                id={name}
                value={value}
                onChange={onChange}
                onBlur={onBlur}
            />
            {touched && error && <span className="text-danger">{error.message}</span>}
        </>
    )}
/>

版本校验

确认你的依赖版本匹配:React Hook Form v6 对应的@hookform/resolvers版本为 1.x 系列,版本不匹配也可能导致校验触发时机异常。

内容的提问来源于stack exchange,提问作者B. Christophe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 09:54:06