heyday2024 님의 블로그
React Hook Form을 이용한 로그인/회원가입 구현 및 트러블슈팅 본문
React Hook Form의 사용 배경 및 장점
React로 로그인/회원가입 폼을 구현할 때 처음에는 useState를 사용하여 각 필드의 상태를 개별적으로 관리했다. 하지만 이렇게 하면 관리해야 할 state가 많아지고, 입력할 때마다 컴포넌트가 리렌더링되는 문제가 발생했다. 이러한 비효율성을 해결하기 위해 react-hook-form을 도입했다.
React Hook Form 장점:
- 간단한 API: 필드 값 관리, 유효성 검사, 제출 핸들러를 간단하게 구현 가능.
- 리렌더링 최소화: 내부적으로 ref를 활용하여 상태를 관리하므로 폼 상태 변경 시 불필요한 리렌더링이 발생하지 않음.
- 유효성 검사 지원: 기본적인 유효성 검사를 쉽게 설정 가능
- 간소화된 코드: 여러 개의 state와 이벤트 핸들러를 사용하지 않고, register, handleSubmit 등을 통해 간결한 코드를 작성할 수 있음.
닉네임 중복 방지와 trigger로 해결한 문제
닉네임 중복 방지는 외부와의 통신(superbase)으로 중복 여부를 확인해야 했는데,
이 경우 React Hook Form의 isValid 상태만으로는 즉각적인 버튼 활성화가 어려웠다.
그래서 trigger를 사용해 특정 필드의 유효성 검사를 수동으로 실행하고, 상태를 업데이트하도록 구현했다.
- trigger: 특정 필드의 유효성 검사를 수동으로 실행, 해당 필드가 유효한지 여부를 React Hook Form의 상태에 반영하는 역할.
useEffect(() => {
// 닉네임 사용 가능 상태가 변경되면 유효성 검사 트리거
trigger("nickname");
}, [nicknameAvailable, trigger]);
이 방식으로 닉네임 중복 검사와 같은 비동기 검증 로직에서도 폼의 유효 상태를 실시간으로 업데이트하고, 버튼 활성화 등의 작업을 처리 가능.
이메일 확인 유효성 검사에서 발생한 지연 업데이트 문제
하지만, 이메일 확인과 같은 동적 유효성 검사에서 trigger를 사용했을 때, 유효성 메세지가 한 박자 늦게(?) 업데이트되는 문제가 발생함. 이 부분을 trigger 사용해서도 구현했을 수 있겠지만 너무 불필요하고 비효율적인 일이라고 판단하고, React Hook Form의 watch와 적절한 조건문을 미리 정의해서 활용함으로서 실시간 유효성 검사를 구현했다.
- watch 설명:
폼 필드의 현재 값을 구독하며, 값이 변경될 때마다 즉각적으로 반영
const passwordPattern = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,20}$/;
const [showPassword, setShowPassword] = useState(false);
const [showConfirmedPassword, setShowConfirmedPassword] = useState(false);
// 실시간으로 password 값 가져오기
const watchPassword = watch("password");
const watchConfirmPassword = watch("confirmPassword");
// 비밀번호 확인 에러 메시지 여부
const confirmPasswordError =
isSignup && watchConfirmPassword !== watchPassword;
{/* 비밀번호 입력창 에러 메시지 */}
{watchPassword && !passwordPattern.test(watchPassword) ? (
<p className="text-red-500 text-sm mt-3">
비밀번호는 6~20자리이며 영문과 숫자를 포함해야 합니다.
</p>
) : (
errors.password && (
<p className="text-red-500 text-sm mt-3">
{errors.password.message}
</p>
)
)}
이 방식으로 비밀번호와 비밀번호 확인 필드의 유효성을 실시간으로 확인하고, 별도의 리렌더링이나 지연 없이 에러 메시지와 버튼 상태를 업데이트할 수 있었음.
+ 추가적으로 trigger, watch 다시 정리
1. watch
역할:
- watch는 폼 필드의 값 변화를 실시간으로 관찰할 수 있게 해주는 훅
- 특정 필드, 혹은 모든 필드의 상태를 반환하며, 컴포넌트가 렌더링될 때 값을 지속적으로 업데이트함.
사용 상황:
- 값의 실시간 반응이 필요한 경우 사용합니다.
- 예:
- 입력한 값에 따라 동적으로 UI를 업데이트해야 할 때.
- 특정 입력값에 따라 다른 입력값을 조건부로 활성화하거나 비활성화해야 할 때.
- 입력 값에 따라 특정 메시지나 경고를 실시간으로 표시해야 할 때.
- 예:
2. trigger
역할:
- trigger는 특정 필드 또는 전체 필드의 유효성 검사를 강제로 실행
- 비동기로 실행되며, 유효성 검사 결과(true 또는 false)를 반환
사용 상황:
- 특정 이벤트에서 명시적으로 유효성 검사를 실행해야 할 때 사용
- 예:
- 사용자가 입력을 완료하지 않았더라도, 특정 조건에서 즉시 유효성 검사를 실행해야 할 때.
- 버튼 클릭 시 필드 상태를 검사한 뒤 추가 동작(예: 폼 제출, 상태 업데이트)을 수행해야 할 때.
- 예:
React Hook Form은 폼 상태 관리와 유효성 검사에서 사용하기 정말 좋은 라이브러리로, 상황에 따라 trigger와 watch를 적절히 잘 활용하면 UX가 좋은 signup, login페이지를 만들 수 있다.