“.Required”验证错误未显示

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

我正在 Vite typescript 中创建一个注册页面,其中我使用 React-hook-form 进行表单处理,并使用 Yup 进行验证。我的注册表单中有 5 个字段:用户名、全名、电子邮件、密码和头像文件输入,现在发生的情况是,我在 YUP 验证的帮助下创建了所需的所有字段,但是当我没有传递任何图像文件时它不会抛出“需要头像”的错误并跳转到无效类型的第二次验证。

这是验证模式的代码:

  const validFileExtensions = ["jpg", "jpeg", "png", "gif", "svg", "webp"];

  function isValidFileType(fileName?: string): boolean {
    if (!fileName) return false;
    const extension = fileName.split(".").pop()?.toLowerCase();
    return extension ? validFileExtensions.includes(extension) : false;
  }

  // validation schema with yup
  const validationSchema = Yup.object().shape({
    email: Yup.string().required("Email is required").email("Email is invalid"),
    password: Yup.string()
      .required("Password is required")
      .min(8, "Password must be at least 8 characters long"),
    fullname: Yup.string().required("Full name is required"),
    username: Yup.string()
      .required("Username is required")
      .min(4, "At least 4 characters ")
      .matches(/^\S+$/, "No spaces allowed"),
    avatar: Yup.mixed<File>()
      .required("Avatar is required")
      .test(
        "fileType",
        "Only JPG, JPEG, PNG, GIF, SVG, and WEBP files are allowed",
        (value) => {
          if (!value) return true;
          return isValidFileType(value.name);
        }
      )
      .test("fileSize", "File must be less than 100KB", (value) => {
        if (!value) return true;
        return value.size <= MAX_FILE_SIZE;
      }),

    // --- .test("fileType", "Unsupported file format", (value) => {
    //   if (!value || value.length === 0) return false;
    //   const file = value[0];
    //   return ["image/jpeg", "image/png"].includes(file.type);
    // })
    // .test("fileSize", "File must be less than 2MB", (value) => {
    //   if (!value || value.length === 0) return false;
    //   const file = value[0];
    //   return file.size <= 2 * 1024 * 1024;
    // }), ---
  });

使用 yupResolver 将 schema 传递到 React hook 形式的代码

 const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<SignUpFormInputs>({
    resolver: yupResolver(validationSchema),
  });

将错误传递到“uploadFileInput”组件的代码

<UploadFileInput
           label="Upload an Avatar"
           id="uploadAvatar"
           name="avatar"
           errors={errors.avatar?.message}
           register={register}
         />

“uploadFileInput”组件的代码

import React from "react";
import { UseFormRegister } from "react-hook-form";
import { RxAvatar } from "react-icons/rx";

interface SignUpFormInputs {
  email: string;
  password: string;
  fullname: string;
  username: string;
  avatar: File;
}

interface UploadFileInputProps {
  id: string;
  label: string;
  name: keyof SignUpFormInputs;
  errors?: string;
  register: UseFormRegister<SignUpFormInputs>;
}

const UploadFileInput: React.FC<UploadFileInputProps> = ({
  id,
  label,
  name,
  register,
  errors,
}) => {
  return (
    <>
      <label
        className="text-[17px]  w-[50%] text-center text-gray-400  text-sm bg-gray-100 file:cursor-pointer p-2 cursor-pointer    file:text-white"
        htmlFor={id}
      >
        <span className=" flex items-center gap-2">
          <RxAvatar size={30} />
          {label}
        </span>
        <input id={id} type="file" className="hidden" {...register(name)} />
        {errors && (
          <p className="absolute  ml-[-9px] text-red-500 text-sm mt-3 ">
            {errors}
          </p>
        )}
      </label>
    </>
  );
};

export default UploadFileInput;

问题来了

Picture if needed

提前致谢。

forms validation react-hook-form yup
1个回答
0
投票

正如你在下面看到的,头像是一个类型为

FileList
的对象,因此它永远不是一个假值。

FileList is not null

您可以做的是为所需文件创建自定义测试:

avatar: yup
  .mixed()
  .test("required", "photo is required", (value) => value.length > 0),
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.