[React] React-Hook-Form

DongEun·2022년 12월 4일
2
post-thumbnail

What is React-Hook-Form?

사용하기 쉬운 유효성 검사와 함께 성능이 뛰어나고 유연하며 확장 가능한 양식.

Form 종류

  • React-Form : 순수 React로 짜여진 Form
  • Redux-Form : redux에서만 사용이 가능하다는게 단점
  • Formik : 3년전까지만해도 유명했었음 클래스형에서 함수형으로 이동하면서 떨어짐(러닝커브가 심함)
  • React-Hook-Form : 함수형에서 제공하는 Hook폼 (간단함) 현재 실무에서 가장 많이 사용함

Why React-Hook-Form?

Less code. More performant

React Hook Form은 불필요한 재렌더링을 제거하면서 작성해야 하는 코드의 양을 줄입니다.

React-Hook-Form은 리렌더가 되지않아요

React는 state가 변하면서 리렌더링을 하게되지않나요?
비제어컴포넌트로 제작이되어있어서 리렌더링이 되지 않아요

콘텐츠가 변경될 때 알림을 useRef 보내지 않는다는 점에 유의 하세요. 속성을 변경해 .current도 다시 렌더링되지 않습니다. React가 ref를 DOM 노드에 연결하거나 분리할 때 일부 코드를 실행하려는 경우 콜백 ref 를 대신 사용할 수 있습니다.
공식 React-useRef

제어컴포넌트와 비제어컴포넌트
제어컴포넌트는 setState가 발생하며 리렌더가 일어나요
1500자의 이력서를 작성할때 버벅거리는게 사용자 눈에 보여요(성능 느림)

사용하는곳?
input창에 신용카드 번호를 작성할떄
처음과 마지막 2글자를 제외하고 나머지가 *로 처리 될떄
진짜값: 1234-1234-1234-1234
보여주는값: 12**-****-****-**34
<input type="text" value={보여주는값}/>

비제어컴포넌트는 리렌더링 발생안해요 (ref)
document.getElementById() => useRef를 이용하여 비제어컴포넌트를 만들 수 있음
1500자의 이력서를 작성할때 버벅거리지 않아요(성능이 빠름)


사용법

signup.container.tsx

export default function Singup() {
  const router = useRouter();
  const { register, handleSubmit, formState } = useForm<IFormData>({
    resolver: yupResolver(schema),
  });
  const [createUser] = useMutation(CREATE_USER);
  const onClickSubmit = async (data: IFormData) => {
    try {
      const result = await createUser({
        variables: {
          createUserInput: {
            ...data,
          },
        },
      });
      console.log(result);
      alert("회원가입을 해주셔서 감사합니다.");
      router.push("/");
    } catch (error) {
      ErrorModal("회원가입", error.message);
    }
  };
  return (
    <SingupUI
      register={register}
      handleSubmit={handleSubmit}
      formState={formState}
      onClickSubmit={onClickSubmit}
    />
  );
}

container에 useForm을 선언하고 prasenter에 register, handleSubmit, formState들을 내려 보내요
register(onChange),handleSubmit(onClick),formState(state)

signup.parsenter.tsx

export default function SingupUI(props) {
  return (
    <>
     <S.Wrapper>
       <S.FormWrap onSubmit={props.handleSubmit(props.onClickSubmit)}>
          <S.Title>AniMap 회원가입</S.Title>
          <input type="text" {...register("email")} />
          <div>{formState.errors.email?.message}</div> 
          <input type="password" {...register("password")} />
          <div>{formState.errors.password?.message}</div> 
          <input type="text" {...register("name")} />
          <div>{formState.errors.name?.message}</div> 
          <S.ButtonWrap>
            <Button01 text="가입하기" />
          </S.ButtonWrap>
        </S.FormWrap>
     </S.Wrapper>
    </>
  );
}

form에서는 button의 타입을 설정하지않으면 기본적으로 submit타입을 갖게되고 클릭하게되면 form의 onSubmit을 호출하게되요 handleSubmit에 onClickSubmit을 감싸서 데이터를 전달할 수 있게되어요

props.formState.errors.스테이트.message는 yup에서 에러가 생겼을때 호출 하는 메세지에요



Validation 라이브러리 Yup

Yup이란?
Yup은 런타임 값 구문 분석 및 유효성 검사를 위한 스키마 빌더입니다. 스키마 정의, 일치하도록 값 변환, 기존 값의 형태 주장 또는 둘 다. Yup 스키마는 매우 표현력이 뛰어나며 복잡하고 상호 의존적인 유효성 검사 또는 값 변환을 모델링할 수 있습니다.

signup.validation.ts

import * as yup from "yup";

export const schema = yup.object({
  email: yup
    .string()
    .required("이메일을 입력해주세요.")
    .email("이메일 형식에 맞춰주세요"),
  password: yup
    .string()
    .required("패스워드를 입력해주세요.")
    .matches(
      /^(?=.*?[a-zA-Z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,16}$/,
      "8자~16자, 숫자/영어대소문자/특수문자를 모두 포함해주세요"
    ),
  name: yup
    .string()
    .required("이름을 입력해주세요.")
    .max(8, "8글자 이하로 작성해주세요"),
});

yup은 유효성검사를 위한 라이브러리에요 좀 더 간편하고 명확한 코드로 줄일수가 있어요

profile
다채로운 프론트엔드 개발자

0개의 댓글