使用React Hook Form+Yup校验时Material UI Select选中后仍报错无法提交
问题根因
- 未将
yupResolver传入useForm配置,导致校验规则和表单状态未正确联动 - 校验类型、默认值、Select组件属性三者不匹配:
- 若为单选场景:Yup校验类型应为
string,默认值设为空字符串"",无需给Select加multiple属性 - 若为多选场景:需给Select加
multiple属性,默认值设为空数组[],Yup校验保留array类型即可
- 若为单选场景:Yup校验类型应为
- 未将
fieldState.error绑定到MUI的FormControl组件的error属性,导致视觉错误状态无法跟随校验结果同步更新 - 原默认值设为空格字符串
" ",和后续选中的有效值对比时会出现匹配异常,导致校验不通过
修正后代码(单选场景,适配你当前未加multiple的Select写法)
import { makeStyles, Box, Select, FormControl, InputLabel, MenuItem, Typography, } from "@material-ui/core"; import * as yup from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; // 注意引入路径要对应resolvers版本 import { useForm, Controller } from "react-hook-form"; const useStyles = makeStyles({ red: { color: '#f44336', fontSize: '0.75rem', marginTop: '3px', marginLeft: '14px' } }); const FormFields = ({ typeOfInquiry, typeOfProviderSupplier, feedbackform }) => { const classes = useStyles(); const schema = yup.object().shape({ // 单选场景用string,非空校验 typeofInquiry: yup.string().trim().required('请选择咨询类型'), }); // 核心:把resolver传入useForm const { handleSubmit, control, reset, formState: { errors } } = useForm({ resolver: yupResolver(schema), mode: 'onChange' // 可选,修改值时实时触发校验 }); const onSubmit = (data) => { console.log('表单提交数据', data); // 后续提交逻辑 }; return ( <form onSubmit={handleSubmit(onSubmit)}> <FormControl style={{ minWidth: 220 }} error={!!errors.typeofInquiry}> <InputLabel id="typeof-inquiry-label">咨询类型</InputLabel> <Controller name="typeofInquiry" render={({ field, fieldState }) => ( <Select labelId="typeof-inquiry-label" label="咨询类型" {...field} > {typeOfInquiry.map((person) => ( <MenuItem key={person.value} value={person.value} > {person.label} </MenuItem> ))} </Select> )} control={control} defaultValue="" // 单选默认值为空字符串 /> <Typography className={classes.red}>{errors.typeofInquiry?.message}</Typography> </FormControl> </form> ); }
多选场景补充修改点
如果是多选需求,只需修改3处即可:
- Select组件加
multiple属性:<Select multiple {...field}> - Yup校验规则改回数组:
typeofInquiry: yup.array().min(1, '请至少选择一项咨询类型').required('请选择咨询类型') - Controller的defaultValue改为空数组:
defaultValue={[]}
内容的提问来源于stack exchange,提问作者Floyd Orr - Baja Tech Space
相关产品推荐
相关产品推荐

