이번 2차 팀 프로젝트에서 로그인, 회원가입 파트를 맡게 되었고 이전에도 사용해보았던 라이브러리인 'React Hook Form'을 사용하기로 결정했다.
먼저, 다음과 같은 간단한 회원가입 Form을 만들어봤다.
const LoginForm = () => {
<form onSubmit={handleSubmit(onSubmit)}>
<p>회원 가입</p>
<p>이름</p>
<input
type='text'
placeholder='이름을 입력해주세요. (최소 2자 이상)'
/>
<p>이메일</p>
<input
type='email'
placeholder='이메일을 입력해주세요.'
/>
<input type='submit' value='회원가입' />
</form>
}
다른 코드들은 생략하고, 회원가입을 구성하는 부분만 들고 왔는데 여기서 보통 라이브러이 없이 회원가입을 구현할 때는 React Hook인 useState를 활용하여 Form에 들어가는 객체 state들을 만들고, input 태그에 onChange 이벤트를 활용하여 사용자가 값을 입력할 때마다 이벤트 관련 로직을 처리하는 방법으로 구현했다.
const LoginForm = () => {
const [values, setValues] = useState({ email: '', password: '' });
return (
<input
type="email"
name="email"
value={values.email}
onChange={handleChange}
/>
)
}
물론.. 이렇게 구현해도 회원가입 기능이 가능하게끔 하는건 가능한데, 문제는 회원가입 Form이 이메일이나 비밀번호 정도만 입력받는 것이 아니라 여러 개의 input, select, textarea로 구성될 수 있다는 점이다. 사용자가 입력하는 값이 많아질수록 내부적으로 많은 상태를 관리해야 하고 컴포넌트의 복잡도가 증가하게 된다.
따라서, Form의 복잡한 상태 관리를 도와줄 Custom Hook을 만들어 관리할 수도 있다.
https://www.daleseo.com/react-forms-with-hooks/
하지만, 나는 Custom Hook을 만들기 보다는 내부적으로 이러한 기법을 사용하고 있는 React-hook-form을 통해 구현하기로 했다.
https://codesandbox.io/s/react-hook-form-get-started-j5wxo
react-hook-form 공식문서의 예제를 먼저 살펴보면, react-hook-form 패키지로부터 useForm() 이라는 Hook 함수를 불러온 후, 결과 객체로부터 register, handleSubmit, ... 등의 함수를 얻을 수 있다.
여기서, 사용자에게 입력을 받을 Input 태그에 register 함수를 등록하고, handleSubmit 함수를 이용하여 form 요소에서 발생하는 submit 이벤트를 처리해준다.
추가로 react-hook-form은 입력값 검증을 정말 쉽게 도와준다. 예를 들어, 이메일이나 비밀번호는 필수 값이고 이메일의 경우에는 유효한 형식을 갖추어야 하고 비밀번호의 길이 최소 길이가 있을 수도 있다. 이러한 입력값 검증에 대해서 예제처럼 register 함수의 두 번째 인자로 옵션을 넘겨주면 된다.
아래와 같이 코드를 짜면, 유효한 형식에 맞지 않을 경우 형식에 맞지 않는다는 에러 메세지를 보여줄 수 있고, 입력값이 없을 경우 필수 입력을 하라는 메시지를 띄울 수 있다. 각 에러에 맞는 에러 메세지를 핸들링 할 수 있게끔 도와준다. 유효하지 않은 입력했을 경우 로그인 폼이 제출되지 않고, formState의 erros 객체에 오류 내용이 저장된다. 이 값을 읽어서 입력란 아래에 오류 메세지를 띄워주면 사용자 입장에서도 확인하기가 용이해진다.
const LoginForm = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm();
return (
<form onSubmit={handleSubmit(onSubmit)}>
<label htmlFor="email">이메일</label>
<input
id="email"
type="text"
placeholder="test@email.com"
{...register("email", {
required: "이메일은 필수 입력입니다.",
pattern: {
value: /\S+@\S+\.\S+/,
message: "이메일 형식에 맞지 않습니다.",
},
})}
/>
{errors.email && <small role="alert">{errors.email.message}</small>}
</form>
)
}
+ 아, 추가적으로 react-hook-form 없이 useState와 onChange 이벤트를 사용해서 구현하면 자식 컴포넌트가 입력값이 바뀔때마다 계속해서 리렌더링 되는 상황이 일어날 수 있는데, react-hook-form은 그런 리렌더링으로부터 독립적으로 Form을 관리해주어 성능상의 이점도 가져갈 수 있다! 또한, 공식문서에 있는 Subscriptions 부분을 보면 Form의 성능은 UX 측면에서 굉장히 중요하다고 말하고 있고, react-hook-form을 이용하면 전체 컴포넌트를 리렌더링 하지 않고도 개별 입력 값 및 상태를 업데이트 할 수 있다고 한다.
'엘리스 SW 엔지니어 트랙 > Project' 카테고리의 다른 글
useState + useEffect, 데이터 처리하기 (0) | 2022.07.18 |
---|---|
CSS로 로딩 스피너를 만들어보자! (0) | 2022.07.17 |
Refresh Token 구현 기록(2) (0) | 2022.06.14 |
Refresh Token 구현 기록(1) (0) | 2022.06.14 |
관리자 권한을 가진 jwt 토큰이 탈취된다면? (0) | 2022.06.01 |