首页 > 解决方案 > Yup.mixed().test() 在 React 中不能与 Formik 一起使用

问题描述

我创建了一个表单并接受了一些输入,例如学生姓名、照片等。我想验证这些输入。为此,我使用 Formik & Yup。

  1. studentName:- 至少 3 个字符,只允许使用 A-Za-z 字符
  2. 照片:- 文件不应大于 1mb,只允许 jpeg 和 png 文件类型

验证 studentName 工作正常,但不适用于照片。当我尝试上传文件时,它总是给出错误,因为上传的文件太大,即使我上传的文件大于 1mb。简而言之,以下条件不起作用。

photo: Yup.mixed()
  .test('FILE_SIZE', 'Uploaded file is too big.', (value) => !value || (value && value.size >= FILE_SIZE))
  .test(
    'FILE_FORMAT',
    'Uploaded file has unsupported format.',
    (value) => !value || (value && SUPPORTED_FORMATS.includes(value.type))
  )

沙盒网址: https ://codesandbox.io/s/ecstatic-mountain-gol1l

import "bootstrap/dist/css/bootstrap.min.css";
import { ErrorMessage, Field, Form, Formik } from "formik";
import React from "react";
import * as Yup from "yup";

export default function App() {
  const FILE_SIZE = 1000000; //1mb
  const SUPPORTED_FORMATS = [
    "image/jpg",
    "image/jpeg",
    "image/png"
  ];

  return (
    <div className="App">
      <Formik
        initialValues={{
          studentName: "",
          photo: null
        }}
        validationSchema={Yup.object().shape({
          studentName: Yup.string()
            .min(3, "Name cannot be less than 3 characters")
            .matches(/^[A-Za-z ]*$/, "Please enter valid name")
            .required("Student Name is required"),
          photo: Yup.mixed()
            .required("A file is required")
            .test(
              "FILE_SIZE",
              "Uploaded file is too big.",
              (value) => !value || (value && value.size >= FILE_SIZE)
            )
            .test(
              "FILE_FORMAT",
              "Uploaded file has unsupported format.",
              (value) =>
                !value || (value && SUPPORTED_FORMATS.includes(value.type))
            )
        })}
        render={({ errors, touched }) => (
          <Form>
            <div className="form-group">
              <label className="col-sm-4 control-label">Student Name</label>
              <div className="col-sm-8">
                <Field
                  id="studentName"
                  name="studentName"
                  type="text"
                  className={
                    "form-control" +
                    (errors.studentName && touched.studentName
                      ? " is-invalid"
                      : "")
                  }
                />
                <ErrorMessage
                  name="studentName"
                  component="div"
                  className="invalid-feedback"
                />
              </div>
            </div>
            <div className="form-group">
              <label className="col-sm-4 control-label">Photo</label>
              <div className="col-sm-8">
                <Field
                  id="photo"
                  name="photo"
                  type="file"
                  className={
                    "form-control" +
                    (errors.photo && touched.photo ? " is-invalid" : "")
                  }
                />
                <ErrorMessage
                  name="photo"
                  component="div"
                  className="invalid-feedback"
                />
              </div>
            </div>
          </Form>
        )}
      />
    </div>
  );
}

标签: javascriptreactjsvalidationformikyup

解决方案


我不知道你是否已经解决了这个问题,但对我来说,问题似乎出在这条线上

(value) => !value || (value && value.size >= FILE_SIZE)

如果 value.size 小于 FILE_SIZE (不像您的代码中那样更大),这应该返回 true。


推荐阅读