Tanstack query와 react-hook-form을 사용하는 프로젝트를 진행하던 중 작은 문제를 발견하였다.
Input에 사용자가 글을 입력할 때마다 tanstack query를 enable 시켜서 데이터를 불러오고 싶었는데 react-hook-form 의 state가 리렌더링이 되지 않아 실행이 되지 않는 것이었다.
react-hook-form 공식 문서 홈을 보니 performance 부분에 대한 설명이 다음과 같이 쓰여져있었다.
Minimizes the number of re-renders, minimizes validate computation, and faster mounting.
react-hook-form이 리렌더링 횟수를 줄여 최적화 한다는 사실은 알고 있었지만 문제를 겪기 전까지 체감하진 못했던 것 같다. 그렇다면 useState를 이용한 controlled component 방식이 아닌 ref를 사용한 unControlled component 방식을 사용하고 있는 것인지 확인해야겠다는 생각이 들었다.
react-hook-form 공식문서에 따르면,
Performance of React Hook Form
Performance is one of the primary reasons why this library was created. React Hook Form relies on an uncontrolled form, which is the reason why the register function captures ref and the controlled component has its re-rendering scope with Controller or useController.
풀어서 설명하자면, 예상대로 react-hook-form 라이브러리는 uncontrolled form에 의존하며, 라이브러리를 사용할 때 필요한 register function은 ref를 사용한다. 하지만, 라이브러리의 Controller나 useController는 controlled component에 의존함을 할 수 있다.
즉, react-hook-form 라이브러리는 주로 uncontrolled component에 의존하지만 controlled component도 사용할 수 있다고 볼 수 있다.
Controller와 useController 사용법은 각각 Controller 설명과 useController 설명에서 확인할 수 있다.
그렇다면 controlled와 unControlled에 대해 알아보자.
제어 컴포넌트는 컴포넌트의 상태나 속성(props)으로 주어진 값을 활용하는 컴포넌트이다. <input>
에서 value 값을 useState로 관리하는 것이 대표적인 제어 컴포넌트의 예시라고 할 수 있겠다.
비제어 컴포넌트는 html 요소 자체적으로 상태를 가져 예를 들어 useState등을 이용한 상태 관리를 따로 하지 않는 컴포넌트이다. <input>
에 값을 입력하면 해당 값은 입력 폼 내부의 상태로 관리된다.
참조(ref)를 이용하여 요소의 상태에 접근할 수 있으며, 상태가 변화하여도 리렌더링이 이루어지지 않아 리액트는 변화를 인식하지 못한다. 그렇기 때문에 데이터와 UI의 동기가 이루어지지 않는다.
이렇게 uncontrolled component를 사용하면서 얻을 수 있는 장점은 다음과 같다.
This approach reduces the amount of re-rendering that occurs due to a user typing in an input or other form values changing at the root of your form or applications. Components mount to the page faster than controlled components because they have less overhead.
즉, 이러한 접근(uncontrolled form)으로 input 또는 form이나 application에서 변경되는 state의 리렌더링의 횟수를 줄일 수가 있다. 이렇게 어떤 기능을 처리하는 데 소요되는 간접적인 처리 시간이 줄어듦으로써 component 마운트 속도도 빨라지게 된다.
이를 수치로 확인하기 위해 react-hook-form 공식문서 performance compare 탭을 보면, 자주 사용하는 form 라이브러리들의 performance 성능을 비교해놓은 사진들을 볼 수가 있다.
React hook Form
Formik
Redux Form
사진에서 확인할 수 있듯이 react-hook-form 의 performance가 비교적 더 좋음을 알 수 있다.
https://merrily-code.tistory.com/74
https://medium.com/fasal-engineering/controlled-and-uncontrolled-components-in-react-js-c3111ee0a864