Heim > Web-Frontend > js-Tutorial > Dynamische Formulare mit diskriminierter Union und React Hook Form

Dynamische Formulare mit diskriminierter Union und React Hook Form

Susan Sarandon
Freigeben: 2024-12-24 03:41:14
Original
1078 Leute haben es durchsucht

Dynamic forms with discriminatedUnion and React Hook Form

Formularvalidierung ist ein entscheidender Aspekt moderner Webanwendungen. Mit Bibliotheken wie React Hook Form (RHF) und Zod können Sie dynamische Formulare effizient validieren, auch solche mit komplexen Strukturen wie Zahlungsmethoden. In diesem Artikel wird erläutert, wie Sie sowohl Zod als auch RHF verwenden, um Formulare mithilfe der leistungsstarken discriminatedUnion dynamisch zu validieren.

Was ist eine diskriminierte Gewerkschaft?

Eine diskriminierte Union ist eine erweiterte Typisierungstechnik, die zum Modellieren von Objekten mit unterschiedlichen Strukturen, aber einem gemeinsamen Unterscheidungsfeld verwendet wird. Dieses Diskriminanzfeld wird verwendet, um zu identifizieren, welcher Subtyp verwendet wird, und um eine entsprechende Validierung oder Manipulation durchzuführen.
Stellen Sie sich beispielsweise ein Zahlungsformular vor, das drei Arten von Zahlungsmethoden enthalten kann:

  1. Kreditkarte (erfordert Kartennummer und CVV)
  2. PayPal (erfordert eine E-Mail-Adresse)
  3. Banküberweisung (erfordert eine Kontonummer und eine Bankleitzahl). Jeder dieser Typen kann mithilfe einer diskriminierten Union modelliert werden Beispiel für Datenmodellierung mit Zod
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>>

Nach dem Login kopieren

**

Wie funktioniert die Validierung?

**

  1. discriminatedUnion überprüft das Typfeld:

    • Wenn der Typ „Kreditkarte“ ist, validiert Zod entsprechend die im ersten Objekt definierten Einschränkungen.
    • Wenn der Typ „Paypal“ ist, werden nur die verknüpften Regeln überprüft zum PayPal-Objekt.
    • Wenn der Typ „bankTransfer“ ist, erfolgt die Validierung entsprechend die Banküberweisungskriterien.
  2. Strenge Validierung:

    • Jeder Typ ist unabhängig. Wenn ein Benutzer stellt einen ungültigen Typ bereit oder lässt ein erforderliches Feld aus, Zod löst einen bestimmten Fehler aus.
  3. Einfachheit für die React-Hook-Form:

    • Das Schema ermöglicht es RHF, die Validierung dynamisch anzupassen Vereinfachen Sie die Logik entsprechend dem Typfeld das Formular.

**

Warum hier eine diskriminierte Union verwenden?

**

  1. Klare Trennung der Verantwortlichkeiten
    • Jede Zahlungsmethode hat spezifische Regeln, die nicht zulässig sind sich gegenseitig stören.
  2. Flexibilität
    • Ermöglicht neue Arten (z. B. eine neue Zahlung). Methode) einfach hinzugefügt werden. Arten (zum Beispiel eine neue Zahlungsmethode).
  3. Sicherheit
    • Stellt sicher, dass ungültige Werte erkannt werden Validierungszeit.

**

Integration mit React Hook Form

**
React Hook Form erleichtert die Verwaltung von Formularen und bleibt dabei leistungsstark und flexibel. Hier erfahren Sie, wie Sie Zod und RHF integrieren, um ein Formular basierend auf „discriminatedUnion“ zu validieren.

import { useForm, SubmitHandler, FieldErrors } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import './zahlung.css';
importieren {
  PaymentMethodEnum,
  paymentMethodSchema,
  PaymentMethodSchemaType,
} aus '../validators/validate-zahlungsschema';

const Payment = () => {
  const form = useForm<PaymentMethodSchemaType>({
    Resolver: zodResolver(zahlungMethodSchema()),
    Standardwerte: {
      Typ: PaymentMethodEnum.CREDIT_CARD,
    },
  });

  const { register, formState, handleSubmit } = form;

  const { Fehler } = formState;

  const paymentType = form.watch().type;

  const handleChangePaymentType = (Typ: PaymentMethodEnum) => {
    form.setValue('type', type);
  };

  const handleResetForm = () => {
    form.reset(GetErrorState(zahlungsTyp));
  };

  const onSubmit: SubmitHandler<PaymentMethodSchemaType> = (Daten) => {
    console.log('data', data);
  };

  const PaymentTypeFormNode: React.ReactNode = (() => {
    switch (Zahlungstyp) {
      case PaymentMethodEnum.BANKTRANSFER:
        const bankTransferErrors = getErrorsByPaymentType(errors, paymentType);

        zurückkehren (
          <div>
            <div className="form">
              <label>Kontonummer</label>
              <Eingabe
                {...register('accountNumber')}
                placeholder="Geben Sie Ihre Kontonummer ein"
              />
              {bankTransferErrors?.accountNumber?.message && (
                <span className="errormessage">
                  {bankTransferErrors.accountNumber.message}
                </span>
              )}
            </div>

            <div className="form">
              <label>Bankleitzahl</label>
              <Eingabe
                {...register('bankCode')}
                placeholder="Geben Sie Ihre Bankleitzahl ein"
              />
              {bankTransferErrors?.bankCode?.message && (
                <span className="errormessage">
                  {bankTransferErrors.bankCode.message}
                </span>
              )}
            </div>
          </div>
        );

      Fall PaymentMethodEnum.CREDIT_CARD:
        const creditCardErrors = getErrorsByPaymentType(errors, paymentType);
        zurückkehren (
          <div>
            <div className="form">
              <label>Kartennummer</label>
              <Eingabe
                {...register('cardNumber')}
                placeholder="Geben Sie Ihre Kartennummer ein"
              />
              {creditCardErrors?.cardNumber && (
                <span className="errormessage">
                  {creditCardErrors.cardNumber.message}
                </span>
              )}
            </div>

            <div className="form">
              <label>CVV</label>
              <Eingabe
                {...register('cvv')}
                placeholder="Geben Sie Ihren Kartenvalidierungscode ein"
              />
              {creditCardErrors?.cvv && (
                <span className="errormessage">
                  {creditCardErrors.cvv.message}
                </span>
              )}
            </div>
          </div>
        );

      case PaymentMethodEnum.PAYPAL:
        const paypalErrors = getErrorsByPaymentType(errors, paymentType);
        zurückkehren (
          <div className="form">
            <label>E-Mail</label>
            <Eingabe
              type="E-Mail"
              {...register('email')}
              placeholder="Geben Sie Ihre E-Mail-Adresse ein"
            />
            {paypalErrors?.email?.message && (
              <span className="errormessage">{paypalErrors.email.message}</span>
            )}
          </div>
        );

      Standard:
        wirf einen neuen Fehler(
          Zahlungstyp „Erschöpfender Schutzfehler: Wert empfangen“.
        );
    }
  })();

  zurückkehren (
    <form className="form-wrapper" onSubmit={handleSubmit(onSubmit)}>
      <div className="form">



<p>**</p>

<h2>
  
  
  Abschluss
</h2>

<p>**<br>
Das ist es also, Leute. Ich hoffe, Sie fanden diesen Artikel hilfreich. discriminatedUnion ist ein Dienstprogrammtyp, der auf viele Arten verwendet werden kann. Wenn Sie der Meinung sind, dass es weitere Möglichkeiten gibt, discriminatedUnion zu verwenden, teilen Sie mir dies bitte in den Kommentaren mit. Vielen Dank, dass Sie diesen Artikel gelesen haben. Wir sehen uns alle in meinem nächsten Artikel?.</p>

<p>Link zur Testanwendung: <br>
https://stackblitz.com/edit/vitejs-vite-ppgw9zrb?file=src/pages/zahlungen.tsx</p>


          

            
        
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonDynamische Formulare mit diskriminierter Union und React Hook Form. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage