개발자
류준열
React Hook Form
React Hook Form으로 form을 만들면 더 적은 코드로 더 많은 기능을 구현할 수 있다.
제어컴포넌트와 비제어컴포넌트
리액트에서는 Form을 만들때 모든 인풋을 state로 관리하거나, ref 기반으로 submit이 발생할때만 form 데이터가 전송되도록 할 수 있다.
전자는 유저의 모든 입력을 제어할 수 있다해서 제어컴포넌트, 후자는 그렇지 않아서 비제어 컴포넌트라고 한다.
제어컴포넌트는 모든 요소를 state로 관리하다보니 이름input을 입력하더라도 해당 state를 선언한 컴포넌트 전체가 리렌더링되게 된다. 반면에 ref 기반의 비제어컴포넌트는 submit 버튼을 클릭할때만 리렌더링이 된다.
그래서 그런지 몰라도 리렌더링을 이유로 react-hook-form을 거론하는 블로그들이 많다. (react hook form은 ref 기반의 비제어컴포넌트 form 라이브러리이다.)
그게 뭐가 중요해?
하지만 나는 유저에게 보이지도 않는 리렌더링을 신경쓰는게 무의미하다고 생각한다.
내 기준에서 아래 gif정도가 아니면 우선순위가 높지 않은 리렌더링이다.
결론적으로 제어니 비제어니 하는 것 보다 유저에게 가치를 주는 기능을 하나 더 만드는게 중요하다고 생각해서 Form을 만드는 방법에 대해서는 크게 신경쓰지 않았다. (내가 지금까지 겪은 문제들이 딱 그정도 수준이었기 때문인 것 같다.)
겪은 문제
회사에서 작업을 하는데, 유저가 선택한 항목에 따라 구성요소가 결정되는 Form을 만들어야 했다.
요약하면 개발자가 Form의 구성요소를 예측할 수 없는 상황이었다. (ex: input의 개수와 각각의 validation)
이를 State로 만들려다보니 reduce
, Array.from({length: count}}..
, 등등 별의 별 배열메소드를 사용하게 되었다.
그럼에도 기획상의 예외처리를 만족하지 못해 결국 버그 투성이의 컴포넌트가 만들어졌다.
간소화된 폼 컨트롤
계속 고민하다가 다음날 React Hook Form으로 다시 만드니 허무하리 만큼 쉽게 만들어졌다...
React Hook Form의 가장 강력한 특징은 어떤 Form이 만들어지건 Form 답게 데이터를 뽑아낼 수 있다는 것이다.
{질문1:답변1, 질문2:답변2,..}
또한 useForm
에서 제공하는 기능들로 데이터를 항상 관찰 할 수 있다.
// watch
const {
...
watch, // Form 내의 구성요소들을 계속 관찰
...
} = useForm<Inputs>();
// watch: 모든 필드가 작성되었는지 알기 위해 watch 활용
const allFieldsFilled = Object.keys(parameters).every((key) => watch(key));
// validation 관리: 서버에서 내려주는(기획에서 정해진) 정규표현식을 프론트에서 바로 활용 const { ... formState: { errors }, ... } = useForm<Inputs>(); ... return ( <div key={key}> <Input label={key} {...register(key, { pattern: regex.pattern })} placeholder={regex.desc || "입력 내용"} /> {errors[key] && ( <ErrorMessage> {regex.desc} </ErrorMessage> )} </div> ); })}
비제어컴포넌트 이상의 react-hook-form
리렌더링을 줄이니 어쩌니 하는게 중요한게 아니다.
React Hook Form을 사용하면 Form을 Form답게 관리 할 수 있다.
{질문1:답변1, 질문2:답변2,..}
또한 라이브러리의 여러 기능들을 이용하여 validation 관리나 데이터 관찰등을 쉽게 할 수 있다.
즉, React Hook Form으로 Form을 만들면 더 적은 코드로 더 많은 기능을 더 쉽게 구현할 수 있다
앞으로는 React Hook Form을 더 자주 사용하게 될 것 같다.