表单输入合法时提交按钮未激活?MUI+React Hook Form+Yup校验问题
多选项互斥表单校验修复方案
现有问题
你当前编写的Yup校验规则仅限制了最少选中1项,没有覆盖「“每天”与其余星期选项互斥」的业务逻辑,因此无法满足校验需求。
修复步骤
1. 完善Autocomplete选项禁用逻辑
在Material UI Autocomplete组件的getOptionDisabled属性中添加互斥判断,实现交互层面的选项禁用效果:
<Autocomplete multiple getOptionDisabled={(option) => { const selected = watch("daysOfWeek"); // 已选“每天”时,禁用所有非“每天”选项 if (selected.some(item => item.label === "每天")) { return option.label !== "每天"; } // 已选其他选项时,禁用“每天” if (selected.length > 0) { return option.label === "每天"; } return false; }} // 其余属性保持不变 />
此处使用React Hook Form的watch方法实时获取daysOfWeek字段的当前选中值。
2. 补充Yup互斥校验规则
在校验Schema中新增自定义test规则,兜底防止极端场景下出现非法提交:
const validationSchema = Yup.object().shape({ daysOfWeek: Yup.array() .of( Yup.object().shape({ label: Yup.string(), disabled: Yup.boolean(), }) ) .min(1, "请选择星期") .test( "daysMutex", "不能同时选择“每天”和其他星期选项", (val) => !val.some(item => item.label === "每天") || val.length === 1 ) });
该规则要求:如果选中了“每天”,则已选列表只能有1项,否则判定为校验不通过。
3. 同步校验触发时机
在Autocomplete的onChange回调中调用setValue时添加shouldValidate: true配置,确保选项变更时实时触发校验,自动更新提交按钮状态:
onChange={(_, newValue) => { setValue("daysOfWeek", newValue, { shouldValidate: true }); }}
提交按钮直接绑定disabled={!formState.isValid}即可实现校验不通过时禁用的效果。
内容的提问来源于stack exchange,提问作者Valerie Hosler
相关产品推荐
相关产品推荐

