是的验证不适用于基于另一个现场条件的条件
Yup validataion not working on condition based on another field condition
我有一个 image
字段,我希望仅当 image_old
字段为空且 poster_type
为 image
时才需要此文件。
这里,poster
类型是一个select框,有两个可能的值script
或image
。接下来,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>
);
}
长话短说:
- 当用户 select
image
为 poster_type 时,它应该显示 image is required
- 如果
image_old
字段不为空,则不应抛出,必需的错误消息,仅当 poster_type
为 image
且 image_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;
}
},
我有一个 image
字段,我希望仅当 image_old
字段为空且 poster_type
为 image
时才需要此文件。
这里,poster
类型是一个select框,有两个可能的值script
或image
。接下来,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>
);
}
长话短说:
- 当用户 select
image
为 poster_type 时,它应该显示image is required
- 如果
image_old
字段不为空,则不应抛出,必需的错误消息,仅当poster_type
为image
且image_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;
}
},