Pengesahan borang ialah aspek penting dalam aplikasi web moden. Dengan perpustakaan seperti React Hook Form (RHF) dan Zod, anda boleh mengesahkan borang dinamik dengan cekap, termasuk yang mempunyai struktur kompleks seperti kaedah pembayaran. Artikel ini menerangkan cara menggunakan kedua-dua Zod dan RHF untuk mengesahkan borang secara dinamik menggunakan discriminatedUnion yang berkuasa.
DiscriminatedUnion ialah teknik menaip lanjutan yang digunakan untuk memodelkan objek dengan struktur berbeza tetapi berkongsi medan diskriminasi yang sama. Medan diskriminasi ini digunakan untuk mengenal pasti subjenis yang sedang digunakan dan untuk melaksanakan pengesahan atau manipulasi sewajarnya.
Sebagai contoh, pertimbangkan borang pembayaran yang mungkin mengandungi tiga jenis kaedah pembayaran:
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 memeriksa medan jenis:
Pengesahan yang ketat :
Kesederhanaan untuk Borang React Hook:
**
**
**
**
React Hook Form memudahkan untuk mengurus borang sambil kekal berprestasi tinggi dan fleksibel. Begini cara untuk mengintegrasikan Zod dan RHF untuk mengesahkan borang berdasarkan discriminatedUnion.
import { useForm, SubmitHandler, FieldErrors } daripada 'react-hook-form'; import { zodResolver } daripada '@hookform/resolvers/zod'; import './payment.css'; import { PaymentMethodEnum, Skema kaedah pembayaran, PaymentMethodSchemaType, } daripada '../validators/validate-payment-schema'; const Bayaran = () => { borang const = useForm<PaymentMethodSchemaType>({ penyelesai: zodResolver(paymentMethodSchema()), defaultValues: { jenis: PaymentMethodEnum.CREDIT_CARD, }, }); const { register, formState, handleSubmit } = form; const { ralat } = formState; const paymentType = form.watch().type; const handleChangePaymentType = (jenis: PaymentMethodEnum) => { form.setValue('jenis', jenis); }; const handleResetForm = () => { form.reset(GetErrorState(paymentType)); }; const onSubmit: SubmitHandler<PaymentMethodSchemaType> = (data) => { console.log('data', data); }; const PaymentTypeFormNode: React.ReactNode = (() => { suis (jenis pembayaran) { case PaymentMethodEnum.BANKTRANSFER: const bankTransferErrors = getErrorsByPaymentType(errors, paymentType); kembali ( <div> <div className="form"> <label>Nombor akaun</label> <masukan {...register('accountNomber')} placeholder="Masukkan nombor akaun anda" /> {bankTransferErrors?.accountNumber?.message && ( <span className="errormessage"> {bankTransferErrors.accountNumber.message} </span> )} </div> <div className="form"> <label>Kod bank</label> <masukan {...daftar('Kod bank')} placeholder="Masukkan kod bank anda" /> {bankTransferErrors?.bankCode?.message && ( <span className="errormessage"> {bankTransferErrors.bankCode.message} </span> )} </div> </div> ); case PaymentMethodEnum.CREDIT_CARD: const creditCardErrors = getErrorsByPaymentType(errors, paymentType); kembali ( <div> <div className="form"> <label>Nombor Kad</label> <masukan {...daftar('Nombor kad')} placeholder="Masukkan nombor kad anda" /> {creditCardErrors?.cardNumber && ( <span className="errormessage"> {creditCardErrors.cardNumber.message} </span> )} </div> <div className="form"> <label>CVV</label> <masukan {...daftar('cvv')} placeholder="Masukkan kod pengesahan kad anda" /> {creditCardErrors?.cvv && ( <span className="errormessage"> {creditCardErrors.cvv.message} </span> )} </div> </div> ); case PaymentMethodEnum.PAYPAL: const paypalErrors = getErrorsByPaymentType(errors, paymentType); kembali ( <div className="form"> <label>E-mel</label> <masukan type="e-mel" {...daftar('e-mel')} placeholder="Masukkan e-mel anda" /> {paypalErrors?.email?.message && ( <span className="errormessage">{paypalErrors.email.message}</span> )} </div> ); lalai: buang Ralat baharu( 'Ekhaustive Guard Error : received value' paymentType ); } })(); kembali ( <form className="form-wrapper" onSubmit={handleSubmit(onSubmit)}> <div className="form"> <p>**</p> <h2> Kesimpulan </h2> <p>**<br> Jadi begitulah kawan-kawan. Saya harap anda mendapati artikel ini membantu. discriminatedUnion ialah jenis utiliti yang boleh digunakan dalam pelbagai cara. Jika anda fikir terdapat lebih banyak cara untuk menggunakan discriminatedUnion, sila beritahu saya dalam ulasan. Terima kasih kerana membaca artikel ini. Jumpa anda semua dalam artikel saya yang seterusnya?.</p> <p>pautan permohonan ujian: <br> https://stackblitz.com/edit/vitejs-vite-ppgw9zrb?file=src/pages/payments.tsx</p>
Atas ialah kandungan terperinci Borang dinamik dengan discriminatedUnion dan React Hook Form. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!