본문 바로가기
개발

react-hook-form + yup으로 효율적인 폼 관리하기

by rious275 2023. 3. 25.

react-hook-form 공식 문서
yup 공식 문서

react-hook-form + yup

react-hook-form은 사용자로부터 데이터를 수집하는 form을 좀 더 효율적으로 관리할 수 있도록 도와주는 라이브러리. 비제어 컴포넌트 방식으로 구현되어 있어 렌더링 이슈를 해결가능하며, yupform의 유효성 검증을 도와주는 라이브라리이며 주로 react-hook-form과 함께 사용한다.

설치

yarn add react-hook-form yup @hookform/resolvers

yup 세팅

우선 유효성 검증을 하기위한 schema를 세팅한다.

import * as yup from "yup";

const schema = yup.object({
  id: yup
    .string()
    .required("아이디를 입력해주세요")
    .min(4, "최소 4글자 이상 입력해주세요!")
    .max(8, "아이디는 최대 8글자입니다!"),
  phone: yup
    .string()
    .required("휴대폰 번호를 입력해주세요")
    .matches(/^[0-9]+$/, "숫자만 입력해 주세요!"),
});

위의 코드처럼 검증 조건을 정리 후 메서드를 사용해 표현한다. 기존에 라이브러리 없이 사용하는 커스텀 훅이나 정규식을 활용하지 않고도 간단히 표현할 수 있다. 극단적으로 표현할 경우, email() 같은 메서드로 극단적으로 편하게 표현할 수도 있다.(아래 코드 참고)

const schema = yup.object({
  email: yup.string().email("이메일 형식에 맞지 않습니다!")
});

매우 다양한 메서드들이 있으니, 최상단에 있는 공식 문서를 참고하여 필요한 메서드를 찾아보자.

yupResolver 적용

유효성에 대한 스키마를 작성했으면, 이제 react-hook-form에 연결해야 한다.

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

const schema = yup.object({
  // 위에서 작성한 스키마
});

interface IExampleTypes {
  id: string;
  phone: string;
}

const App = () => {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<IExampleTypes>({
    mode: "onChange",
    resolver: yupResolver(schema),
  });

  // 폼 제출 시 실행되는 Submit 함수 (파라미터 안에 입력값들이 들어있다)
  const onSubmit: SubmitHandler<IExampleTypes> = data => {
    console.log(data);
  };

  return (
    <Container>
      <form onSubmit={handleSubmit(onSubmit)}>
        <div className="input-wrapper">
          <div>
            <input type="text" placeholder="아이디" {...register("id")} />
            <p>{errors.id?.message}</p>
          </div>
          <div>
            <input type="text" placeholder="휴대폰" {...register("phone")} />
            <p>{errors.phone?.message}</p>
          </div>
        </div>
        <button>Submit</button>
      </form>
    </Container>
  );
}

위 예제처럼 useFormresolveryupResolver(schema)를 등록해준다. 기본적인 적용까지 살펴보았고, 이후에 watch, useWatch와 리렌더 이슈에 대해 확인해보겠다.