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"元素。
解决步骤
修正下拉框绑定逻辑
确保多选下拉框的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)); }} />
- 原生
临时修复验证逻辑(若无法立即调整下拉框)
要是暂时改不了下拉框的绑定,可以在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.
相关产品推荐
相关产品推荐

