表单验证是现代 Web 应用程序的一个重要方面。借助 React Hook Form (RHF) 和 Zod 等库,您可以有效地验证动态表单,包括具有复杂结构(例如支付方式)的表单。本文介绍了如何使用 Zod 和 RHF 来使用强大的 discriminatedUnion 动态验证表单。
discriminatedUnion 是一种高级类型技术,用于对具有不同结构但共享公共判别字段的对象进行建模。该判别字段用于识别正在使用哪种子类型并相应地执行验证或操作。
例如,考虑一个可能包含三种付款方式的付款表单:
import * as zod from "zod" const IsNotEmptyString = (message: string) => zod.string({message}).min(1, {message}) export enum PaymentMethodEnum { CREDIT_CARD ="creditCard", PAYPAL = "paypal", BANKTRANSFER ="bankTransfer" } const creditCardSchema = zod.object({ type: zod.literal(PaymentMethodEnum.CREDIT_CARD), cardNumber: zod.string().regex(/^\d{16}$/, "The card number must contain 16 digits"), cvv: zod.string().regex(/^\d{3}$/, "The Card Validation Code must contain 3 digits"), }) const paypalSchema = zod.object({ type: zod.literal(PaymentMethodEnum.PAYPAL), email: zod.string().email("PayPal email is invalid"), }) const bankTransferSchema = zod.object({ type: zod.literal(PaymentMethodEnum.BANKTRANSFER), accountNumber: IsNotEmptyString("The account number must contain at least 10 characters"), bankCode: IsNotEmptyString("The bank code must contain at least 4 characters") }) export const paymentMethodSchema = () => zod.discriminatedUnion("type",[ creditCardSchema, paypalSchema,bankTransferSchema ]); export type PaymentMethodSchemaType = zod.infer < ReturnType <typeof paymentMethodSchema>>
**
**
discriminatedUnion 检查类型字段:
严格验证:
React Hook 表单的简单性:
**
**
**
**
React Hook Form 可以轻松管理表单,同时保持高性能和灵活性。下面介绍如何集成 Zod 和 RHF 来验证基于 discriminatedUnion 的表单。
从 'react-hook-form' 导入 { useForm, SubmitHandler, FieldErrors }; 从 '@hookform/resolvers/zod' 导入 { zodResolver }; 导入'./ payment.css'; 进口 { 付款方式枚举, 付款方式架构, PaymentMethodSchemaType, 来自 '../validators/validate- payment-schema'; 常量支付 = () => { const form = useForm<paymentmethodschematype>({ 解析器:zodResolver( paymentMethodSchema() ), 默认值:{ 类型:PaymentMethodEnum.CREDIT_CARD, }, }); const { 注册,formState,handleSubmit } = 表单; const { 错误 } = formState; const paymentType = form.watch().type; const handleChangePaymentType = (类型: PaymentMethodEnum) => { form.setValue('类型', 类型); }; const handleResetForm = () =>; { form.reset(GetErrorState( paymentType) ); }; const onSubmit: SubmitHandler<paymentmethodschematype>; =(数据)=> { console.log('数据', 数据); }; const PaymentTypeFormNode: React.ReactNode = (() => { 开关(付款类型){ 案例 PaymentMethodEnum.BANKTRANSFER: const BankTransferErrors = getErrorsByPaymentType(错误, paymentType); 返回 ( <div> <div className="form"> 帐号标签> > {bankTransferErrors?.accountNumber?.message && ( <span classname="错误消息"> {bankTransferErrors.accountNumber.message} </span> )} </span> </div> <div className="form"> 银行代码标签> > {bankTransferErrors?.bankCode?.message && ( <span className="错误消息"> {bankTransferErrors.bankCode.message} </span> )} ; ); 案例 PaymentMethodEnum.CREDIT_CARD: const CreditCardErrors = getErrorsByPaymentType(错误, paymentType); 返回 ( <div> <div className="form"> 卡号标签> > {creditCardErrors?.cardNumber && ( <span className="错误消息"> {creditCardErrors.cardNumber.message} </span> )} </div> <div className="form"> CVV标签> > {creditCardErrors?.cvv && ( <span className="错误消息"> {creditCardErrors.cvv.message} </span> )} ); 案例 PaymentMethodEnum.PAYPAL: const paypalErrors = getErrorsByPaymentType(错误, paymentType); 返回 ( <div className="form"> 电子邮件标签> > {paypalErrors?.email?.message && ( <span classname="errormessage">{paypalErrors.email.message}</span>; )} ); 默认: 抛出新的错误( “详尽的防护错误:收到值” paymentType ); } })(); 返回 ( <form classname="form-wrapper" onsubmit="{handleSubmit(onSubmit)}">; <div classname="form"> <p>**</p> <h2> 结论 </h2> <p>**<br> 就是这样,伙计们。我希望这篇文章对您有所帮助。 discriminatedUnion 是一种实用程序类型,可以通过多种方式使用。如果您认为还有更多使用 discriminatedUnion 的方法,请在评论中告诉我。感谢您阅读本文。我们下一篇文章见?.</p> <p>测试申请链接:<br> https://stackblitz.com/edit/vitejs-vite-ppgw9zrb?file=src/pages/ payments.tsx</p> </div> </form></paymentmethodschematype></paymentmethodschematype>
以上是具有 discriminatedUnion 和 React Hook Form 的动态表单的详细内容。更多信息请关注PHP中文网其他相关文章!