Formik+Yup场景下如何仅在对应表单元素存在时执行校验?
解决方案
你完全可以通过Yup内置的条件校验能力实现需求,不需要手动编写冗长的按钮禁用判断,也不会触发未渲染字段的校验。
核心实现方式:用Yup.when()定义关联校验规则
直接在校验Schema中声明字段的校验触发条件,只有条件满足时才会执行对应字段的校验逻辑,不满足条件的字段不会生成校验错误,formik.isValid的返回值就会符合预期。
你场景对应的校验Schema示例如下:
import * as Yup from 'yup'; const formSchema = Yup.object().shape({ // 基础必填字段 covidStatus: Yup.string().required('请选择新冠感染状态'), // 仅当covidStatus选择"是"时,igTest才必填 igTest: Yup.string().when('covidStatus', { is: 'covidYes', then: (schema) => schema.required('请选择Ig检测结果'), otherwise: (schema) => schema.notRequired(), }), // 仅当covidStatus选"是"且igTest选"是"时,testDate、igNumber才必填 testDate: Yup.string().when(['covidStatus', 'igTest'], { is: (covidStatus, igTest) => covidStatus === 'covidYes' && igTest === 'IgYes', then: (schema) => schema.required('请填写检测日期'), otherwise: (schema) => schema.notRequired(), }), igNumber: Yup.string().when(['covidStatus', 'igTest'], { is: (covidStatus, igTest) => covidStatus === 'covidYes' && igTest === 'IgYes', then: (schema) => schema.required('请填写检测编号'), otherwise: (schema) => schema.notRequired(), }), // 仅当covidStatus选"是"且igTest选"否"时,covidDate才必填 covidDate: Yup.string().when(['covidStatus', 'igTest'], { is: (covidStatus, igTest) => covidStatus === 'covidYes' && igTest === 'IgNo', then: (schema) => schema.required('请填写感染日期'), otherwise: (schema) => schema.notRequired(), }), });
Formik配置调整
把上面写好的Schema传给Formik组件的validationSchema属性即可,原来的validateOnMount等配置不需要修改,下一步按钮直接用以下逻辑就可以:
<button disabled={!formik.isValid}>下一步</button>
更复杂场景的备选方案
如果你的表单字段是完全动态增删的(不是简单的条件渲染),也可以调用Formik提供的setValidationSchema方法,在字段渲染/卸载时动态更新全局校验规则,灵活度更高。
内容的提问来源于stack exchange,提问作者AlmaG3st
相关产品推荐
相关产品推荐

