表單驗證是現代 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> )} </div> <div classname="form"> 銀行代碼標籤> > {bankTransferErrors?.bankCode?.message && ( <span classname="錯誤訊息"> {bankTransferErrors.bankCode.message} </span> )} </div> </div>; ); 案例 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> )} </div> </div> ); 案例 PaymentMethodEnum.PAYPAL: const paypalErrors = getErrorsByPaymentType(錯誤, paymentType); 返回 ( <div classname="form"> 電子郵件標籤> > {paypalErrors?.email?.message && ( <span classname="errormessage">{paypalErrors.email.message}</span>; )} </div> ); 預設: 拋出新的錯誤( “詳盡的防護錯誤:收到值” 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中文網其他相關文章!