> 웹 프론트엔드 > JS 튜토리얼 > DiscriminateUnion 및 React Hook Form을 사용한 동적 양식

DiscriminateUnion 및 React Hook Form을 사용한 동적 양식

Susan Sarandon
풀어 주다: 2024-12-24 03:41:14
원래의
1043명이 탐색했습니다.

Dynamic forms with discriminatedUnion and React Hook Form

양식 유효성 검사는 최신 웹 애플리케이션의 중요한 측면입니다. RHF(React Hook Form) 및 Zod와 같은 라이브러리를 사용하면 결제 방법과 같은 복잡한 구조를 포함하는 동적 양식을 효율적으로 검증할 수 있습니다. 이 문서에서는 Zod와 RHF를 모두 사용하여 강력한 discriminateUnion을 사용하여 동적으로 양식을 검증하는 방법을 설명합니다.

DiscriminatedUnion이란 무엇인가요?

discriminatedUnion은 구조는 다르지만 공통 식별 필드를 공유하는 객체를 모델링하는 데 사용되는 고급 타이핑 기술입니다. 이 판별 필드는 사용 중인 하위 유형을 식별하고 그에 따라 검증 또는 조작을 수행하는 데 사용됩니다.
예를 들어 세 가지 유형의 결제 방법이 포함된 결제 양식을 생각해 보세요.

  1. 신용카드(카드 번호 및 CVV 필요)
  2. PayPal(이메일 주소 필요)
  3. 은행 송금(계좌 번호 및 은행 코드 필요) 이러한 각 유형은 discriminateUnion을 사용하여 모델링할 수 있습니다. 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>>

로그인 후 복사

**

유효성 검사는 어떻게 작동하나요?

**

  1. DiscriminatedUnion은 유형 필드를 검사합니다.

    • 유형이 'creditCard'인 경우 Zod는 다음에 따라 유효성을 검사합니다. 첫 번째 객체에 정의된 제약 조건
    • 유형이 'paypal'인 경우 연결된 규칙만 확인합니다. PayPal 객체에.
    • 유형이 'bankTransfer'인 경우 다음에 따라 유효성을 검사합니다. 은행송금 기준
  2. 엄격한 검증 :

    • 각 유형은 독립적입니다. 사용자인 경우 잘못된 유형을 제공하거나 필수 필드가 누락되었습니다. Zod가 특정 오류를 유발합니다.
  3. React Hook 형식의 단순성:

    • 스키마를 통해 RHF는 유효성 검사를 동적으로 조정할 수 있습니다. 유형 필드에 따라 논리를 단순화합니다. 양식입니다.

**

여기서 discriminateUnion을 사용하는 이유는 무엇입니까?

**

  1. 명확한 책임 분담
    • 각 결제 수단별 규칙은 다음과 같습니다. 서로 간섭합니다.
  2. 유연성
    • 새로운 유형 허용(예: 새로운 결제) 방법)을 쉽게 추가할 수 있습니다. 유형(예: 새로운 결제 방법)
  3. 보안
    • 잘못된 값이 감지되었는지 확인합니다. 검증 시간입니다.

**

React Hook 양식과 통합

**
React Hook Form을 사용하면 고성능과 유연성을 유지하면서 양식을 쉽게 관리할 수 있습니다. DiscriminateUnion을 기반으로 양식을 검증하기 위해 Zod와 RHF를 통합하는 방법은 다음과 같습니다.

'react-hook-form'에서 { useForm, SubmitHandler, FieldErrors } 가져오기;
import { zodResolver } from '@hookform/resolvers/zod';
가져오기 './결제.css';
수입 {
  결제 방법Enum,
  지불 방법스키마,
  결제 방법스키마 유형,
} '../validators/validate-지불-스키마'에서;

const 결제 = () => {
  const form = useForm<PaymentMethodSchemaType>({
    해결 프로그램: zodResolver(결제 방법 스키마()),
    기본값: {
      유형: PaymentMethodEnum.CREDIT_CARD,
    },
  });

  const { 레지스터, formState, handlerSubmit } = 양식;

  const { 오류 } = formState;

  const PaymentType = form.watch().type;

  const handlerChangePaymentType = (유형: PaymentMethodEnum) => {
    form.setValue('type', 유형);
  };

  const handlerResetForm = () => {
    form.reset(GetErrorState(결제 유형));
  };

  const onSubmit: SubmitHandler<PaymentMethodSchemaType> = (데이터) => {
    console.log('데이터', 데이터);
  };

  const PaymentTypeFormNode: React.ReactNode = (() => {
    스위치(결제 유형) {
      사례 PaymentMethodEnum.BANKTRANSFER:
        constbankTransferErrors = getErrorsByPaymentType(errors, PaymentType);

        반품 (
          <div>
            <div className="form">
              <라벨>계좌번호</라벨>
              <입력
                {...등록('계정번호')}
                placeholder="계좌번호를 입력하세요"
              />
              {bankTransferErrors?.accountNumber?.message && (
                <span className="errormessage">
                  {bankTransferErrors.accountNumber.message}
                </스팬>
              )}
            </div>

            <div className="form">
              <라벨>은행 코드</라벨>
              <입력
                {...등록('은행코드')}
                placeholder="은행 코드를 입력하세요"
              />
              {bankTransferErrors?.bankCode?.message && (
                <span className="errormessage">
                  {bankTransferErrors.bankCode.message}
                </스팬>
              )}
            </div>
          </div>
        );

      사례 PaymentMethodEnum.CREDIT_CARD:
        const CreditCardErrors = getErrorsByPaymentType(errors, PaymentType);
        반품 (
          <div>
            <div className="form">
              <라벨>카드번호</라벨>
              <입력
                {...등록('카드번호')}
                placeholder="카드번호를 입력하세요"
              />
              {creditCardErrors?.cardNumber && (
                <span className="errormessage">
                  {creditCardErrors.cardNumber.message}
                </스팬>
              )}
            </div>

            <div className="form">
              <라벨>CVV</label>
              <입력
                {...등록('cvv')}
                placeholder="카드 확인 코드를 입력하세요"
              />
              {creditCardErrors?.cvv && (
                <span className="errormessage">
                  {creditCardErrors.cvv.message}
                </스팬>
              )}
            </div>
          </div>
        );

      사례 PaymentMethodEnum.PAYPAL:
        const paypalErrors = getErrorsByPaymentType(errors, PaymentType);
        반품 (
          <div className="form">
            <라벨>이메일</라벨>
            <입력
              유형="이메일"
              {...등록('이메일')}
              placeholder="이메일을 입력하세요"
            />
            {paypalErrors?.email?.message && (
              <span className="errormessage">{paypalErrors.email.message}</span>
            )}
          </div>
        );

      기본:
        새로운 오류 발생(
          '철저한 가드 오류: 받은 값' 결제 유형
        );
    }
  })();

  반품 (
    <form className="form-wrapper" onSubmit={handleSubmit(onSubmit)}>
      <div className="양식">



<p>**</p>

<h2>
  
  
  결론
</h2>

<p>**<br>
그게 다입니다. 이 기사가 도움이 되었기를 바랍니다. discriminateUnion은 다양한 방법으로 사용할 수 있는 유틸리티 유형입니다. DiscriminateUnion을 사용하는 더 많은 방법이 있다고 생각하시면 댓글로 알려주세요. 이 기사를 읽어주셔서 감사합니다. 다음 글에서 모두 만나보실 수 있나요?.</p>

<p>테스트 신청 링크: <br>
https://stackblitz.com/edit/vitejs-vite-ppgw9zrb?file=src/pages/paids.tsx</p>


          

            
        
로그인 후 복사

위 내용은 DiscriminateUnion 및 React Hook Form을 사용한 동적 양식의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿