Yup条件验证异常:React Hook Form未按预期触发验证
解决React Hook Form结合Yup时初始isValid不符合预期的问题
问题分析
你当前的Yup schema中,email字段仅在满足is条件(输入包含@.+)时才会执行正则验证,但当条件不满足时,字段仅被校验为字符串类型——空字符串或任意字符串都会被判定为有效,这就导致React Hook Form的isValid初始状态为true,不符合你"初始状态invalid,仅当is=true时根据验证结果更新isValid"的需求。
解决方案
我们需要调整Yup schema,让字段在不满足is条件时强制处于invalid状态,同时在满足条件时执行正则验证。这里提供两种可行方案:
方案一:利用when的otherwise配置
在when方法中添加otherwise选项,指定当is条件不满足时的验证规则,直接返回验证失败:
const regex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ export const emailSchema = yup.object().shape({ email: yup .string() .when({ is: (val: string) => { return /@.+/.test(val) }, then: yup.string().matches(regex, { message: 'Invalid Email' }), // 当不满足is条件时,强制验证失败 otherwise: yup.string().test('initial-invalid', 'Please enter a valid email', () => false) }), })
方案二:自定义验证逻辑(更简洁)
直接使用test方法整合所有逻辑,无需依赖when:
const regex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ export const emailSchema = yup.object().shape({ email: yup.string().test('email-validation', 'Invalid Email', (val) => { // 若值满足@.+的格式,用正则校验;否则直接返回false(状态invalid) if (/@.+/.test(val)) { return regex.test(val) } return false }), })
效果说明
- 初始状态(输入为空或不包含
@.+):字段验证失败,React Hook Form的isValid为false - 当输入满足
@.+格式时:执行正则验证,若匹配成功则isValid变为true,失败则保持false
内容的提问来源于stack exchange,提问作者me-me
相关产品推荐
相关产品推荐

