로그인, 회원가입 React-Hook-Form으로 변경하기

yesung·2024년 2월 3일
1
post-thumbnail

변경 이유

기존에는 별도의 form 라이브러리를 사용하지 않고 직접 onChange를 관리하는 훅유효성 검사를 하는 훅 을 별도로 만들어서 관리했는데 React Hook Form 은 이 둘 모두를 관리해 줄 뿐더러 불필요한 코드의 양을 줄일 수 있었고 더 간결해질 수 있었다. 그리고 이전에는 하나의 컴포넌트에서 4개의 폼을 관리하다 보니까 조건부 렌더링으로 보여지는 부분만 렌더링을 했지만 React Dev Tools로 확인해 본 결과 불필요한 부분까지 렌더링이되고 있었고 유지보수가 취약해서 따로 관리하고자 도입하기로 판단했다.

이전 구현 기록: 로그인/회원가입 폼 구현

해당 라이브러리를 적용 시키면서 공식 문서 참고를 굉장히 많이 했는데 상당히 잘 되어있다.

적용

const {
    getValues,
    register,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm<Inputs>({ mode: 'onChange' });

먼저 useForm 훅을 기본적으로 제공해줘서 다양한 함수들을 사용할 수 있도록 해준다.

사용했었던 코드들 위주로 작성해보면

getValues 현재 input 값에 담겨 있는 값을 들어오게 해준다.
register input값에 검증 로직을 적용할 수 있게 헤주는 메서드이다.
handleSubmit form 양식 submit
watch input 값에 담겨 있는 값을 실시간으로 확인할 수 있다.

그리고 mode 라는 옵션도 있다.

onChange : input 값이 바뀔 때마다 검증 로직 동작

onBlur : 포커스 상태를 잃어 버릴떄 동작

onSubmit : submit 함수가 실행될 때 동작

onTouched : 첫 번째 blur 이벤트에서 동작하고 그 후에는 모든 change 이벤트에서 동작

all : blur 및 change 이벤트에서 동작


나는 input을 별도로 반복되는 코드이다 보니 컴포넌트로 분리했고

<input
  className={clsx(inputStyle, { [styles.inputError]: error }, { [styles.inputSuccess]: isSuccessful })}
  type={type}
  minLength={minLength}
  maxLength={maxLength}
  placeholder={placeholder}
  disabled={isSuccessful}
  onKeyDown={isKeyDown ? keyDownLoginHandler : undefined}
  {...(register && register(name, validation))}

안에 들어갈 요소들은 따로 객체 형태로 보관해서 사용될 컴포넌트에서 map으로 그려줬다.

export const signupInput = [
  {
    id: 1,
    label: '사용하실 이메일과 비밀번호를 입력해 주세요.',
    type: 'text',
    placeholder: '이메일',
    name: 'email',
    validation: {
      required: '이메일은 필수 항목입니다.',
      pattern: {
        value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
        message: '이메일 형식에 맞지 않습니다.',
      },
    },
  },
  {
    id: 2,
    type: 'password',
    placeholder: '비밀번호',
    name: 'password',
    minLenght: 8,
    maxLength: 16,
    validation: {
      required: '비밀번호는 필수 항목입니다.',
      minLength: {
        value: 6,
        message: '비밀번호는 최소 8자리 이상이어야 합니다.',
      },
      pattern: {
        value: /^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,16}$/g,
        message: '비밀번호는 영문, 숫자, 특수문자를 포함해야 합니다.',
      },
    },
  },
  
  ... 등등

위 Input 컴포넌트에서 ...(register && register(name, validation)) 를 보면 validation이 들어가는데 위 pattren 들로 처리한다. (해당 값 자체를 정규표현식으로 검사)

errors의 경우 validation 중 input 속성에서 지정한 pattern 객체 내에 있는 message 를 유효성 실패 시, 보여준다. (상당히 유용함)

원래 처음에는 하드 코딩으로 계속 사용했지만 반복되고 많아지다 보니 가독성이 좋지도 않았고 따로 분리해서 사용하면 다른 곳에서도 쓰일 수 있는 장점이 있기에 모듈화했다.

profile
Frontend Developer

0개의 댓글