React中如何根据useState布尔状态为Material UI TextField条件应用Yup验证
解决Yup条件验证不生效的问题
问题根源
你的条件逻辑写反了,且appearing需作为表单values的一部分(Yup的.when()依赖schema关联的表单字段值,而非单独的useState变量)。
正确实现步骤
修正验证逻辑:
需求是「已毕业(appearing为false)时必填毕业年份,在读(appearing为true)时跳过验证」,因此.when()的判断条件应为is: false,同时给otherwise设置非必填规则。将
appearing纳入表单字段:
单独的useState无法被Yup识别,需要把appearing作为表单核心字段之一(比如用Formik管理时,初始values包含该字段)。
完整代码示例
// 以Formik+Material UI为例 import { useFormik } from 'formik'; import * as Yup from 'yup'; import { TextField, Checkbox, FormControlLabel, Button } from '@mui/material'; const formik = useFormik({ initialValues: { appearing: false, yearOfPassing: '' }, validationSchema: Yup.object({ appearing: Yup.boolean(), yearOfPassing: Yup.string().when('appearing', { is: false, // 已毕业状态触发必填验证 then: (schema) => schema.required('毕业年份为必填项'), otherwise: (schema) => schema.notRequired() // 在读状态跳过验证 }) }), onSubmit: (values) => { console.log('表单提交值:', values); } }); return ( <form onSubmit={formik.handleSubmit} style={{ display: 'flex', flexDirection: 'column', gap: '16px', padding: '20px' }}> <FormControlLabel control={ <Checkbox checked={formik.values.appearing} onChange={formik.handleChange} name="appearing" color="primary" /> } label="仍在读" /> <TextField label="毕业年份" name="yearOfPassing" value={formik.values.yearOfPassing} onChange={formik.handleChange} onBlur={formik.handleBlur} error={formik.touched.yearOfPassing && Boolean(formik.errors.yearOfPassing)} helperText={formik.touched.yearOfPassing && formik.errors.yearOfPassing} disabled={formik.values.appearing} variant="outlined" /> <Button type="submit" variant="contained" color="primary"> 提交 </Button> </form> );
关键说明
.when()的第一个参数必须是schema中已定义的字段名,Yup会根据该字段的实时值切换验证规则。- 当TextField被禁用时,
otherwise分支的notRequired()会跳过必填验证,符合需求。 - 若未使用Formik,需确保你的表单状态管理工具能将
appearing与yearOfPassing的状态同步到Yup可访问的上下文。
内容的提问来源于stack exchange,提问作者Dhanashree sagane
相关产品推荐
相关产品推荐

