使用 YUP 验证文件存在

cap*_*013 12 reactjs yup formik

我正在使用Yup来验证我的表单。在我的一种形式中,我想验证<input type="file" />一个文件是否存在。

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

Yup.object().shape({
  file: Yup.object().shape({
    name: Yup.string().required()
}).required('File required')
Run Code Online (Sandbox Code Playgroud)

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

file 必须是一种object类型,但最终值是:(null从值转换{})。如果“null”打算作为空值,请确保将架构标记为.nullable()

任何的想法?

2JN*_*2JN 32

我是这样做的

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
  }),
})
Run Code Online (Sandbox Code Playgroud)


agm*_*984 27

我是这样解决的:

const schema = Yup.object().shape({
    file: Yup.mixed().required('File is required'),
})
Run Code Online (Sandbox Code Playgroud)

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


Jay*_*Xon 7

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

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;
    }
  })
});
Run Code Online (Sandbox Code Playgroud)

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

使用useFormik钩子,您将能够从中捕获错误:

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

formik.errors[Form.File]
Run Code Online (Sandbox Code Playgroud)


Dan*_*Dan 5

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

当验证器运行时,它首先测试字段类型是否匹配。在这种情况下,它会检查它是否是一个对象。由于它不是,并且该字段未标记为nullable,因此验证失败并出现类型错误。是的required(),它永远不会达到跑步的地步,因为它会提前保释。

那么当类型不匹配并且不想使用该nullable()方法时,我们如何调整显示的消息呢?我查看了源代码,发现消息是在此处生成的。所以它是 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')
Run Code Online (Sandbox Code Playgroud)

现在,当类型不正确时,您的新消息将显示。该label()方法允许您为该字段设置一个很好的显示名称,因为该消息将在验证器中的任何无效类型情况下使用。

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