问题描述
所以我在使用 yup 进行条件验证时遇到了问题。
基本上,当复选框未切换时,我希望运输具有所需的属性。
我正在使用 yup 的 when
功能,但我不知道如何从该 sameShippingAsBilling
嵌套对象中引用 shipping
布尔值。
当复选框为 false 时,一切正常,显示错误...
但是当复选框被选中时,我收到这个错误:"Cannot use 'in' operator to search for 'default' in undefined"
问题是 is
回调中的值未定义。
是否可以从这些嵌套对象访问 when
中的外部变量。这样做的替代方法是什么?
这里是沙箱 example
const schema = Yup.object({
sameShippingAsBilling: Yup.bool(),billing: Yup.object({
line1: Yup.string().required(),city: Yup.string().required(),country: Yup.string().required()
}),shipping: Yup.object({
line1: Yup.string().when("sameShippingAsBilling",{
is: !val || val === false,then: Yup.string().required(),}),city: Yup.string().when("sameShippingAsBilling",country: Yup.string().when("sameShippingAsBilling",})
})
});
const addrValues = { line1: "",city: "",country: "" };
const formOpts = {
mode: "onChange",reValidateMode: "onChange",defaultValues: {
sameShippingAsBilling: true,billing: { ...addrValues },shipping: { ...addrValues }
},resolver: yupResolver(schema)
};
export default function CheckoutForm() {
const methods = useForm(formOpts);
const { watch } = methods;
const shippingAsBilling = watch("sameShippingAsBilling");
const onSubmit = async (data) => {
console.log(data);
};
return (
<MuiThemeProvider theme={createMuiTheme()}>
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(onSubmit)} novalidate>
<pre>errors: {JSON.stringify(methods.errors,null,2)}</pre>
<div className="group">
<FormTextField name="billing.line1" />
<FormTextField name="billing.city" />
<FormTextField name="billing.country" />
</div>
<div>
<FormCheckBox name="sameShippingAsBilling" />
</div>
{!shippingAsBilling && (
<div className="group">
<FormTextField name="shipping.line1" />
<FormTextField name="shipping.city" />
<FormTextField name="shipping.country" />
</div>
)}
<div>
<button type="submit">Pay</button>
</div>
</form>
</FormProvider>
</MuiThemeProvider>
);
}
解决方法
您可以根据 shipping
值有条件地渲染 sameShippingAsBilling
对象的形状。
大致如下:
sameShippingAsBilling: Yup.bool(),shipping: Yup.object().when("sameShippingAsBilling",{
is: (sameShippingAsBilling) => !sameShippingAsBilling,then: Yup.object().shape({
line1: Yup.string().required(),city: Yup.string().required(),country: Yup.string().required(),}),otherwise: Yup.object().shape({
line1: Yup.string(),city: Yup.string(),country: Yup.string(),
,
嗯,我在运输中添加了 .nullable().default(null)
,显然它有效。
从技术上讲仍然无法访问布尔值真/假,它可以工作,因为 val 未定义并且它添加了所需的条件......
对于临时解决方案,它很好,我不必摆弄 .test() 或其他奇怪的解决方案。
现在我什至不在乎一个库将其称为“死的简单对象模式验证”,而我却在这些简单的事情上浪费时间。