react-hook-form+Material UI+Yup如何实现文件上传必填校验
解决方法
你当前代码不生效的核心原因是 Yup.mixed().required() 仅会校验值是否为 null/undefined,而未选择文件时 input 返回的是长度为0的FileList对象,不属于 null/undefined,因此会绕过必填校验,按以下两个步骤调整即可生效:
1. 调整Yup校验规则
需要在原有必填校验的基础上新增自定义逻辑,判断文件列表长度是否大于0,修改后代码如下:
const validationSchema = Yup.object().shape({ photo: Yup.mixed() .required("File is required") // 新增自定义校验,判断是否选中了至少一个文件 .test("fileExists", "File is required", (value) => { // 兼容值为undefined、空FileList两种场景 return value && value.length > 0; }), }); const { control, handleSubmit, formState: { errors }, reset, setError, } = useForm({ resolver: yupResolver(validationSchema), // 可选配置:明确设置字段初始默认值 defaultValues: { photo: undefined } });
2. 调整文件输入组件代码
原有逻辑基本可以保留,建议优化错误提示的样式匹配MUI规范,修改后代码如下:
{/******************************************************** PHOTO *********************************************************/} <Controller name="photo" control={control} render={({ field }) => ( <TextField inputRef={field.ref} fullWidth label="photo" margin="dense" accept="image/*" type="file" onChange={(e) => { field.onChange(e.target.files); handleChange(e); // 保留你原有自定义的change处理逻辑 }} InputLabelProps={{ shrink: true, }} error={!!errors.photo} /> )} /> <Typography variant="inherit" color="error"> {errors.photo?.message} </Typography>
调整完成后,未选择文件触发表单提交时就会正常抛出必填错误提示,选中文件后校验自动通过。
内容的提问来源于stack exchange,提问作者Santhosh
相关产品推荐
相关产品推荐

