使用 YUP 验证文件存在

问题描述 投票:0回答:5

我正在使用 是的 来验证我的表单。在我的一张表单中,我想验证

<input type="file" />
是否拥有文件。

我已经测试过这个(它不起作用):

Yup.object().shape({
  file: Yup.object().shape({
    name: Yup.string().required()
}).required('File required')

我在控制台中看到以下错误消息:

file 必须是

object
类型,但最终值为:
null
(强制转换 来自值
{}
)。如果“null”是一个空值,请确保 将架构标记为
.nullable()

有什么想法吗?

reactjs formik yup
5个回答
25
投票

我是这样做的

import { object, string, mixed } from "yup"

const schema = object().shape({
  attachment: mixed().test("fileSize", "The file is too large", (value) => {
    if (!value.length) return true // attachment is optional
    return value[0].size <= 2000000
  }),
})

21
投票

我是这样解决的:

const schema = Yup.object().shape({
    file: Yup.mixed().required('File is required'),
})

如果您尝试在没有文件的情况下提交表单,它会引发错误,而当您有文件时,错误就会消失。


8
投票

我知道这是一个老问题,但我遇到了同样的问题并追踪了发生的事情。

当验证器运行时,它首先测试字段类型是否匹配。在本例中,它检查它是否是一个对象。由于它不是,并且该字段未标记为

nullable
,因此验证失败并出现类型错误。是的,永远不会到达运行的地步
required()
,因为它很早就退出了。

那么当类型不匹配并且不想使用

nullable()
方法时我们如何调整显示的消息呢?我查看了源代码,发现该消息是在here生成的。所以它是 locale 对象的一部分。因此,我们可以这样解决。

import * as Yup from 'yup';
import { setLocale } from 'yup';

setLocale({
  mixed: {
    notType: '${path} is required',
  }
})

Yup.object().shape({
  file: Yup.object().shape({
  name: Yup.string().required()
}).label('File')

现在,当类型不正确时,将显示您的新消息。

label()
方法允许您为字段设置一个漂亮的显示名称,因为该消息将在验证器中的任何无效类型情况下使用。

另一种选择是专门为此字段编写一个自定义验证器,但在这种情况下这似乎有点矫枉过正。


5
投票

其他答案肯定是正确的。这是我已经习惯遵循的另一种方法。

const validationSchema = Yup.object().shape({
 [Form.File]: Yup.mixed()
  .test({
    message: 'Please provide a supported file type',
    test: (file, context) => {
      const isValid = ['png', 'pdf'].includes(getExtension(file?.name));
      if (!isValid) context?.createError();
      return isValid;
    }
  })
  .test({
    message: `File too big, can't exceed ${MAX_FILE_SIZE}`,
    test: (file) => {
      const isValid = file?.size < MAX_FILE_SIZE;
      return isValid;
    }
  })
});

getExtension
是一个自定义实用程序,用于获取文件的 ext 类型。由于 Yup 通常与 Formik 一起使用,上下文参数将允许您显示与您放入的测试相关的错误消息。

使用

useFormik
钩子,您将能够从中获取错误:

const formik = useFormik({
  validationSchema,
  initialValues,
  onSubmit
});

formik.errors[Form.File]

0
投票

这对我有用:

file: yup.object().shape({
  name: yup.string().required('File Required')
  }).required()

  const [file, setFile] = useState(null)  

  const _test = (data) => {
      const _fromData = new FormData();
      _fromData.append('file', file);
  }  

  const handleFileChange = (event) => {
    setFile(event.target.files[0]);
    setValue('file', event.target.files[0].name);
    clearErrors('file');    
  } 

然后我们将以下内容添加到表单中,这将消除文件选择上的错误:

onSubmit={handleSubmit(_test)}

然后我们可以显示错误,如下所示:

{errors?.file?.name?.message}
© www.soinside.com 2019 - 2024. All rights reserved.