개발자
류준열

React Hook Form

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}}.., 등등 복잡한 Array 메소드들을 사용해야 했다.

그리고 버그 투성이가 만들어졌다.

간소화된 폼 컨트롤

계속 고민하다가 다음날 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

제어컴포넌트면 전체가 리렌더링되고, 비제어컴포넌트면 Submit 할 때 한 번 리렌더링되고 이런게 중요한게 아니다.

어차피 유저한텐 안보인다. 불편함이 느껴지지 않는다면 유저는 내부 동작에 관심이 없다.

React Hook Form의 가치는 리렌더링 제거에 있는것이 아니라, 개발자가 제품을 더 쉽게 개발할 수 있도록 돕는 데 있다.