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

React中使用Yup的.when()进行条件验证失效问题排查

问题

我是React和Yup的新手,现有一个包含多选下拉框bookTypeStrings的表单:当选中“Other”选项时,会显示对应的Other文本框,且该文本框需在“Other”选中时设为必填项。但当前的条件验证未正常工作:选中“Other”后清空文本框并失焦,并未触发必填提示。

相关代码如下:

const validationSchema = yup.object({
    ...
    otherBookType: yup
        .string()
        .max(50, 'Must be 50 chars or less')
        .when('bookTypeStrings', (bookTypeStrings, schema) => {
            console.log('in conditional check');
            console.log('bookTypeStrings: ' + bookTypeStrings);
            if (bookTypeStrings.includes('Other')) {
                console.log('Other is selected');
                return schema.required('Required if Other is selected');
            } else {
                console.log('Other is not selected');
                return schema;
            }
        })
});

...

function BookDetailPage() {
    const [otherBookType, setOtherBookType] = useState<string>('');
    const [bookTypeStrings, setBookTypeStrings] = React.useState<string[]>([]);
}

运行后控制台输出如下:

in conditional check
bookTypeStrings: A,B,Other
Other is not selected

请问为何判断未进入if分支,反而执行了else分支?

原因分析与解决方案

核心问题

你控制台打印的bookTypeStrings: A,B,Other看起来是数组转字符串的结果,但实际你的bookTypeStrings数组结构异常——大概率是下拉框绑定错误,把所有选中选项拼成了一个字符串塞进了数组(比如数组是["A,B,Other"]而非["A","B","Other"])。这时候用bookTypeStrings.includes('Other')自然匹配不到,因为数组里没有单独的"Other"元素。

解决步骤

  1. 修正下拉框绑定逻辑
    确保多选下拉框的onChange事件正确生成单个值组成的数组:

    • 原生select带multiple属性时:
      <select
        multiple
        value={bookTypeStrings}
        onChange={(e) => {
          const selectedValues = Array.from(e.target.selectedOptions).map(opt => opt.value);
          setBookTypeStrings(selectedValues);
        }}
      >
        {/* 选项定义 */}
      </select>
      
    • 若使用react-select等UI库:
      <Select
        isMulti
        options={yourOptionList}
        value={bookTypeStrings.map(type => ({ value: type, label: type }))}
        onChange={(selectedItems) => {
          setBookTypeStrings(selectedItems.map(item => item.value));
        }}
      />
      
  2. 临时修复验证逻辑(若无法立即调整下拉框)
    要是暂时改不了下拉框的绑定,可以在Yup验证里兼容异常的数组结构:

    .when('bookTypeStrings', (bookTypeStrings, schema) => {
        console.log('bookTypeStrings原始结构: ', bookTypeStrings); // 直接打印数组看真实内容
        let hasOther = false;
        if (Array.isArray(bookTypeStrings)) {
            // 检查数组里是否存在独立的"Other"元素
            hasOther = bookTypeStrings.some(item => item.trim() === 'Other');
        } else if (typeof bookTypeStrings === 'string') {
            hasOther = bookTypeStrings.includes('Other');
        }
        return hasOther ? schema.required('Required if Other is selected') : schema;
    })
    

内容的提问来源于stack exchange,提问作者LOL. NO.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 11:27:42