[React] 폼 라이브러리

yeni·2022년 12월 2일
0

폼 라이브러리

폼 라이브러리를 사용하면 굉장히 간편하게 코딩을 할 수 있다. 폼 라이브러리는 검증을 대신해주는 폼, state를 대신해주는 폼 등 종류가 매우 다양하다.

  • 제어컴포넌트 : setState발생 ⇢ 리렌더링, 버벅거림, 성능 느림
  • 비제어컴포넌트 : 리렌더링 발생하지 않음, 버벅거리지 않음, 성능 빠름
    ex) document.getElementById(), useRef
    보통 간단한 폼을 사용할 때는 비제어컴포넌트를 사용하고,
    신용카드 정보 등 중요한 데이터를 저장하고 있다면 제어 컴포넌트를 이용하는 것이 좋다.

react-hook-form

설치 : yarn add react-hook-form

import { useForm } from "react-hook-form";

interface IFormData {
  writer: string;
  title: string;
  contents: string;
  boardAddress: {
    addressDetail: string;
  };
}

export default function ReactHookFormPage() {
  const { register, handleSubmit } = useForm<IFormData>();

  const onClickSubmit = (data: IFormData) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onClickSubmit)}>
      작성자 : <input type="text" {...register("writer")} />
      제목 : <input type="text" {...register("title")} />
      내용 : <input type="text" {...register("contents")} />
      {/* 주소 : <input type="text" {...register("boardAddress.addressDetail")} />  객체 안에 객체 타입일 때 */}
      <button>등록하기</button>
    </form>
  );
}

{...register("writer")}를 통해서 우리가 이제까지 했던 onChangeWriter, setWriter 등을 대체할 수 있다.

💡register, handleSubmit, form
register : state를 등록하는데 필요한 모든 기능이 들어있습니다.
handleSubmit : resister에 적힌 state를 등록해주는 함수 입니다.
form : 실제 html에 있는 input들을 묶어주는 태그입니다.

💡button type 정리

<button type="button">기본버튼(장바구니담기)</button>
<button type="reset">지우기</button>
<button type="submit">등록하기</button>
  • reset : form 내부의 input 값이 모두 삭제 됩니다.
  • submit : form 내부의 input 값이 백엔드로 보내집니다. → 기본값 입니다.
  • button : 나만의 버튼을 만들고 싶을때 사용합니다.
  • button의 기본 타입은 submit이므로, form 안에도 submit 함수를 만들고, button 자체에도 함수를 만들었을 경우 둘다 실행되게 된다.

검증 라이브러리(yup)

yup: 비밀번호가 숫자인지, 문자인지, 최소 8자리인지 등 까다로운 검증 단계를 대신해주는 라이브러리

yup과 같은 검증 라이브러리는 보통 form과 함께 사용하며, 리액트 훅 품과 사용할 수 있도록 잘 정리되어있다.
설치 :
yarn add yup
yarn add @hookform/resolvers

import { useForm } from "react-hook-form";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";

const schema = yup.object({
  writer: yup.string().required("작성자를 입력해주세요."),
  title: yup.string().required("제목을 입력해주세요"),
  contents: yup.string().required("내용을 입력해주세요."),
  // .min(8, "8개보다 커야됩니다.")
  // .max(10, "10개보다 작아야됩니다.")
  // .email("이메일 필수입니다.")
});

interface IFormData {
  writer: string;
  title: string;
  contents: string;
  // boardAddress: {
  //   addressDetail: string;
  // };
}

export default function ReactHookFormPage() {
  const { register, handleSubmit, formState } = useForm<IFormData>({
    resolver: yupResolver(schema),
    // react hook form에 yup을 등록한 것.
    mode: "onChange", // 이렇게하면 리렌더링이 됨.
  });

  const onClickSubmit = (data: IFormData) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onClickSubmit)}>
      작성자 : <input type="text" {...register("writer")} />
      <div style={{ color: "red" }}>{formState.errors.writer?.message}</div>
      제목 : <input type="text" {...register("title")} />
      <div style={{ color: "red" }}>{formState.errors.title?.message}</div>
      내용 : <input type="text" {...register("contents")} />
      <div style={{ color: "red" }}>{formState.errors.contents?.message}</div>
      {/* 주소 : <input type="text" {...register("boardAddress.addressDetail")} />  객체 안에 객체 타입일 때 */}
      <button
        style={{ backgroundColor: formState.isValid ? "yellow" : "black" }}
      >
        등록하기
      </button>
    </form>
  );
}
import * as yup from "yup";

export const schema = yup.object({
    writer: yup.string().required("작성자를 입력해주세요."),
    title: yup.string().required("제목을 입력해주세요"),
    contents: yup.string().required("내용을 입력해주세요."),
    // .min(8, "8개보다 커야됩니다.")
    // .max(10, "10개보다 작아야됩니다.")
    // .email("이메일 필수입니다.")
  
    email: yup
      .string()
      .email("이메일 형식에 적합하지 않습니다.")
      .required("이메일은 필수 입력입니다."),
    password: yup
      .string()
      .min(4, "비밀번호는 최소 4자리 이상 입력해주세요.")
      .max(15, "비밀번호는 최대 15자리로 입력해주세요.")
      .required("비밀번호는 필수 입력입니다."),
    phone: yup
      .string()
      .matches(/^\d{3}-\d{3,4}-\d{4}$/, "휴대폰 형식에 알맞지 않습니다.")
      .required("휴대폰은 필수 입력입니다."),
  });

useForm을 커스텀 훅이라고 부른다.

profile
차곡차곡 쌓는 몌으니 개발노트

0개의 댓글