React Hooks 도입 후 Custom Hook으로 폼 로직 정리하기
배경
회원가입, 로그인, 프로필 수정 등 폼을 다루는 컴포넌트가 늘어나면서 비슷한 상태 관리 코드가 반복되고 있었다. React 16.8에서 Hooks가 정식 출시된 후 몇 달간 관망하다가, 이번 스프린트에서 본격적으로 적용해보기로 했다.
useForm 구현
가장 기본적인 폼 로직을 Custom Hook으로 분리했다.
import { useState } from 'react';
function useForm(initialValues) {
const [values, setValues] = useState(initialValues);
const [errors, setErrors] = useState({});
const handleChange = (e) => {
const { name, value } = e.target;
setValues(prev => ({
...prev,
[name]: value
}));
};
const handleSubmit = (callback) => (e) => {
e.preventDefault();
callback(values);
};
return {
values,
errors,
setErrors,
handleChange,
handleSubmit
};
}
사용 예시
로그인 폼에서 이렇게 사용할 수 있다.
function LoginForm() {
const { values, handleChange, handleSubmit } = useForm({
email: '',
password: ''
});
const onSubmit = async (data) => {
try {
await api.login(data);
} catch (error) {
console.error(error);
}
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input
name="email"
value={values.email}
onChange={handleChange}
/>
<input
name="password"
type="password"
value={values.password}
onChange={handleChange}
/>
<button type="submit">로그인</button>
</form>
);
}
결과
Class 컴포넌트로 작성했던 기존 폼들을 모두 Hooks로 전환했다. 컴포넌트당 평균 50줄 정도 코드가 줄었고, 테스트 작성도 더 간단해졌다. 다만 팀원들이 적응하는데 1~2주 정도 시간이 필요했다.
다음 단계로는 validation 로직도 Hook에 통합할 예정이다.