기존에는 별도의 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 를 유효성 실패 시, 보여준다. (상당히 유용함)
원래 처음에는 하드 코딩으로 계속 사용했지만 반복되고 많아지다 보니 가독성이 좋지도 않았고 따로 분리해서 사용하면 다른 곳에서도 쓰일 수 있는 장점이 있기에 모듈화했다.