是的验证不适用于基于另一个现场条件的条件

Yup validataion not working on condition based on another field condition

我有一个 image 字段,我希望仅当 image_old 字段为空且 poster_typeimage 时才需要此文件。

这里,poster类型是一个select框,有两个可能的值scriptimage。接下来,image_old 保存文件名,如 picture.png,这是 poster image 的值,只有在编辑时才有值。 (因为,我使用相同的组件进行创建和编辑)

我的代码如下:

import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as Yup from "yup";

export function App() {
  const schema = Yup.object({
    poster_type: Yup.string()
      .required()
      .oneOf(["image", "script"])
      .label("Poster Type"),
    image: Yup.mixed().when(["image_old", "poster_script"], {
      is: (poster_script, image_old) => {
        if (poster_script === "image" && image_old === "") {
          return true;
        }
      },
      then: (schema) =>
        schema
          .test("name", "Image is required", (value) => {
            return value !== undefined && value[0] && value[0].name !== "";
          })
          .test("fileSize", "File must be less than 2MB", (value) => {
            return value !== undefined && value[0] && value[0].size <= 2000000;
          })
          .test("type", "Only images are supported", (value) => {
            return (
              value !== undefined && value[0] && value[0].type.includes("image")
            );
          }),
      otherwise: (schema) => schema.nullable()
    })
  });

  const {
    register,
    handleSubmit,
    formState: { errors }
  } = useForm({
    resolver: yupResolver(schema)
  });

  const onSubmit = async (input) => {
    console.log("input", input);
  };

  // const item = {
  //   id: 12,
  //   image_old: "old_image.png"
  // };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <select
        className={`form-control w-full ${
          errors["poster_type"] ? "border-red-500" : ""
        }`}
        id="poster_type"
        name="poster_type"
        autoComplete="off"
        {...register("poster_type")}
      >
        <option value="">-- Select --</option>
        <option value="image">Image</option>
        <option value="script">Script</option>
      </select>
      <span
        className={
          errors["poster_type"] ? "text-red-500 text-xs italic block" : "hidden"
        }
      >
        {errors["poster_type"]?.message}
      </span>

      <input
        className={`form-control
                        block
                        w-full
                        px-3
                        py-1.5
                        text-base
                        font-normal
                        text-gray-700
                        bg-white bg-clip-padding
                        border border-solid border-gray-300
                        rounded focus:outline-none ${
                          errors["image"] ? "border-red-500" : ""
                        }`}
        type="file"
        id="image"
        {...register("image")}
      />
      <span
        className={
          errors["image"] ? "text-red-500 text-xs italic block" : "hidden"
        }
      >
        {errors["image"]?.message}
      </span>
      <input type="hidden" defaultValue="" {...register("image_old")} />

      <input type="submit" />
    </form>
  );
}

长话短说:

  1. 当用户 select image 为 poster_type 时,它应该显示 image is required
  2. 如果 image_old 字段不为空,则不应抛出,必需的错误消息,仅当 poster_typeimageimage_old 不应为时才应显示空。

这里是 sandbox link.

我认为这只是您的 image 验证器的错字 我只是把它改成了这个,它似乎有效

    image: Yup.mixed().when(["image_old", "poster_type"], {
      is: (image_old, poster_type) => {
        if (poster_type === "image" && image_old === "") {
          return true;
        }
      },