Formik结合Yup实现仅可见字段必填校验的开发问题咨询
实现方案
有两种成熟的实现方式,可根据你的业务场景选择:
方案1:动态生成校验Schema(改动最小)
直接利用组件内的show状态动态生成Yup校验规则,Formik会自动识别校验Schema的变更并重新触发校验:
- 调整原有的schema定义,改为依赖
show状态的动态值:
const schema = yup.object().shape({ comment: yup.string().required(), // 仅当show为true时,endComment才需要必填校验 endComment: show ? yup.string().required() : yup.string().notRequired() });
- 其他代码无需修改,复选框切换
show状态时校验规则会自动生效/失效。如果需要在隐藏endComment时清空残留值,可以在addEndComment方法中补充逻辑:
const addEndComment = (value: boolean, formik: any) => { setShow(value); if (!value) { // 隐藏时清空endComment的值 formik.setFieldValue('endComment', ''); } }; // 调用时传入formikProps onChange={(e) => addEndComment(e.target.checked, formikProps)}
方案2:把显示状态纳入Formik管理(逻辑更统一)
如果show状态需要随表单一起提交到后端,推荐把show作为Formik的表单字段统一管理,用Yup的when方法实现条件校验:
- 删除独立的
showuseState和addEndComment方法,在Formik的initialValues中新增show字段:
initialValues={{ comment: props.event.comment, endComment: props.event.endComment, show: props.event.endDate ? true : false }}
- 调整校验Schema,使用
when做条件判断:
const schema = yup.object().shape({ comment: yup.string().required(), show: yup.boolean(), endComment: yup.string() .when('show', { is: true, then: (rule) => rule.required(), otherwise: (rule) => rule.notRequired() }) });
- 把复选框的绑定改为Formik受控:
<Form.Check type="checkbox" label={t('event.form-resolve-event.checkbox-label')} checked={formikProps.values.show} onChange={formikProps.handleChange} name="show" />
内容的提问来源于stack exchange,提问作者Greg-A
相关产品推荐
相关产品推荐

