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

配置Yup校验规则:实现3个输入框至少填2个且仅提示文本变红

解决方案

要实现「3个输入框至少填写2个」的Yup校验,并且仅让提示文本变红,你可以按照以下步骤配置:

1. 导入依赖

确保你已经安装了 yup 和 @hookform/resolvers,然后在组件中导入:

import * as Yup from 'yup';
import { yupResolver } from '@hookform/resolvers/yup';
import { useForm } from 'react-hook-form';

2. 定义Yup校验规则

通过 Yup.object().test() 编写自定义校验逻辑,将错误信息绑定到你原代码中使用的 extendDevice 路径上,确保样式判断生效:

const { register, handleSubmit, formState: { errors } } = useForm({
  resolver: yupResolver(
    Yup.object().shape({
      // 三个字段仅做类型兼容,不单独校验
      serialNumber: Yup.string().nullable(),
      businessNumber: Yup.string().nullable(),
      pinNumber: Yup.number().nullable(),
    }).test(
      'at-least-two-fields',
      '',
      function(value) {
        const { serialNumber, businessNumber, pinNumber } = value;
        // 统计已填写的字段数量(排除空字符串、null、undefined)
        const filledCount = [serialNumber, businessNumber, pinNumber].filter(
          item => item !== null && item !== '' && item !== undefined
        ).length;

        // 未满足条件时抛出错误,指定错误路径为extendDevice
        if (filledCount < 2) {
          return this.createError({
            path: 'extendDevice',
            message: t('common:errors.atLeastTwoFields'),
          });
        }
        return true;
      }
    )
  ),
  defaultValues: {
    serialNumber: '',
    businessNumber: '',
    pinNumber: null,
  },
});

3. 调整表单代码

  • 移除 Paper 组件上的 {...register('extendDevice')}(不需要注册这个字段,错误通过Yup手动绑定)
  • 将表单的提交逻辑绑定到 form 标签的 onSubmit 属性,而非按钮的 onClick:
<form onSubmit={handleSubmit(onSubmit)}>
  {!loading ? (
    <Paper title={t('common:cardTitles.extendDevice')}>
      {/* 原头部提示区域保持不变 */}
      <div className="flex md:flex-row flex-col justify-center items-center md:justify-between border-b-[1px] md:pb-6 pb-[17px]">
        <h3 className="font-bold subheading">{t('common:deviceData')}</h3>
        <div className="flex flex-row gap-1">
          <ErrorIcon className={`text-${errors.extendDevice ? 'red-600' : '#80858F'} w-6`} />
          <p
            className={mergeClasses(
              'md:text-sm text-xs',
              errors.extendDevice ? 'text-red-600' : 'text-[#80858F]',
            )}
          >
            {t('common:errors.atLeastTwoFields')}
          </p>
        </div>
      </div>

      {/* 输入框区域保持不变,仅保留register注册 */}
      <div className="md:pt-6 pt-[17px] grid md:grid-cols-2 gap-4">
        <TextInput
          {...register('serialNumber')}
          label={t('common:labels.serialNumber')}
          name="serialNumber"
          placeholder={t('common:placeholders.typeSerialNumber')}
        />
        <TextInput
          {...register('businessNumber')}
          label={t('common:labels.businessNumber')}
          name="business-number"
          placeholder={t('common:placeholders.typeBusinessNumber')}
        />
      </div>
      <div className="pt-4">
        <NumberInput
          {...register('pinNumber')}
          label={t('common:labels.pin')}
          name="pin-number"
          placeholder={t('common:placeholders.typePinNumber')}
        />
      </div>

      {/* 按钮移除onClick,保留type="submit" */}
      <div className="flex w-full justify-end pt-4">
        <Button
          className="py-3.5 px-6 bg-[#336BB3] text-white md:w-[115px] w-full"
          label={t('common:labels.verify')}
          type="submit"
        />
      </div>
    </Paper>
  ) : (
    <VerificationInProgress />
  )}
</form>

关键说明

  • 自定义校验通过 this.createError 指定错误路径为 extendDevice,完美匹配你原代码中 errors.extendDevice 的样式判断逻辑
  • 三个输入框仅做类型兼容,不添加单独的必填校验,避免输入框自身显示错误状态
  • 提交表单时,React Hook Form 会自动触发整个Schema的校验,未满足条件时提示文本自动变红

内容的提问来源于stack exchange,提问作者Jan Bo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:27:11