You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 05:51:02