我正在使用 React-Hook-Form 实现动态表单的 Yup 验证。验证要求取决于
contentType
的值。如果 contentType
是 undefined
或 "Blog Post"
,则应要求 blogPostSchema
,如果 contentType
是 "Product Listing"
,则必须要求 productListingSchema
,如果 contentType
是 "Event"
,则必须要求eventSchema
应该是必需的。
如何构建我的 Yup 模式来正确处理这些情况?
无论
contentType
中存在什么值,blogPostSchema
、productListingSchema
和 eventSchema
仍按要求标记。
这是我当前的代码:
import * as yup from "yup";
const blogPostSchema = yup.object().shape({
blogPostBody: yup.string().required("Body is required"),
blogPostTags: yup.string().required("Tags are required"),
});
const productListingSchema = yup.object().shape({
productName: yup.string().required("Product Name is required"),
price: yup
.number()
.required("Price is required")
.typeError("Price must be a number")
.positive("Price must be a positive number")
.min(1, "Price must be at least 1"),
category: yup.string().required("Category is required"),
});
const eventSchema = yup.object().shape({
eventDate: yup
.date()
.required("Event Date is required")
.typeError("Please enter a valid date"),
location: yup.string().required("Location is required"),
description: yup.string().required("Description is required"),
});
export const schema = yup
.object({
contentType: yup.string().required("Content type is required"),
title: yup.string().required("Title is required"),
author: yup.string().required("Author is required"),
blogPosts: yup
.array()
.of(blogPostSchema)
.when("contentType", {
is: (value) => value === "Blog Post" || value === undefined,
then: (schema) => schema.required(),
otherwise: (schema) => schema.notRequired(),
}),
productListings: yup
.array()
.of(productListingSchema)
.when("contentType", {
is: "Product Listing",
then: (schema) => schema.required(),
otherwise: (schema) => schema.notRequired(),
}),
events: yup
.array()
.of(eventSchema)
.when("contentType", {
is: "Event",
then: (schema) => schema.required(),
otherwise: (schema) => schema.notRequired(),
}),
})
.required();
我在您的代码中看到的第一个错误是没有使用
then
和 otherwise
的函数,如果您使用的是最新版本的 yup
。
这是SO的答案,可能会有所帮助。
现在,我不明白对于每个
title
是否必须始终需要author
和contentType
。从您提出的架构来看,我认为它们应该始终是必需的。
import * as yup from "yup";
// Define schemas for different content types
const blogPostSchema = yup.object().shape({
blogPostBody: yup.string().required("Body is required"),
blogPostTags: yup.string().required("Tags are required"),
});
const productListingSchema = yup.object().shape({
productName: yup.string().required("Product Name is required"),
price: yup
.number()
.required("Price is required")
.typeError("Price must be a number")
.positive("Price must be a positive number")
.min(1, "Price must be at least 1"),
category: yup.string().required("Category is required"),
});
const eventSchema = yup.object().shape({
eventDate: yup
.date()
.required("Event Date is required")
.typeError("Please enter a valid date"),
location: yup.string().required("Location is required"),
description: yup.string().required("Description is required"),
});
export const schema = yup.object().shape({
contentType: yup.string().required("Content type is required"),
title: yup.string().required("Title is required"),
author: yup.string().required("Author is required"),
blogPosts: yup.array().when("contentType", {
is: "Blog Post",
then: () =>
yup.array().of(blogPostSchema).required("Blog Posts are required"),
otherwise: (schema) => schema.notRequired(),
}),
productListings: yup.array().when("contentType", {
is: "Product Listing",
then: () =>
yup
.array()
.of(productListingSchema)
.required("Product Listings are required"),
otherwise: (schema) => schema.notRequired(),
}),
events: yup.array().when("contentType", {
is: "Event",
then: () => yup.array().of(eventSchema).required("Events are required"),
otherwise: (schema) => schema.notRequired(),
}),
});
注意
otherwise
和 then
是函数。无论 Title
为何,Author
和 contentType
现在始终为必填字段。根据所选的 contentType
,特定于内容的字段仍然是有条件必需的。
如果有帮助请告诉我!
这是显示演示的沙盒