useDeferredValue를 활용한 교재 제목 중복검사 API 연동
현재 진행하고 있는 스터디플래너 프로젝트에서 교재를 추가할 수 있는 LibraryAddModal.jsx가 존재한다. 해당 컴포넌트에서 교재의 이름을 입력할 때 중복이 되는지를 검사하는 API 연동을 통해 교재의 이름이 중복되는지 판단한다.



해당 기능을 구현하는 과정에서 useDeferredValue 훅을 사용하였다. 해당 성능 최적화 훅은 이전에 리액트 공식문서를 기반으로 정리한 적이 있다. https://no2jfamily.tistory.com/101
React 공식문서 도장깨기(9) - useDeferredValue
9월 11일에 정리하는 공식문서 주제는 useDeferredValue이다. useTransition과 동일선상에 있는 개념이다. https://react-ko.dev/reference/react/useDeferredValue# useDeferredValue – ReactThe library for web and native user interfa
no2jfamily.tistory.com
해당 과정에서 발생한 이슈가 있었는데 바로 타이핑을 칠 때마다 유효하다는 표시를 제공해주는 CheckIcon.jsx가 재 렌더링 되는것이었다. 어제까지 문제의 원인을 찾지 못했는데 11월 30일 오늘! 공식문서의 내용을 다시 천천히 읽어보면서 문제의 원인을 발견할 수 있었다. 일단 기존의 로직 중 일부는 다음과 같았다.


코드를 보면 CheckIcon 컴포넌트로 총 4개의 props를 넘긴다(bookName, loading, isDuplicate, deferredBookName) bookName은 Input의 onChange 이벤트 헨들러를 통해서 실시간으로 상태 값이 변하게 되고 이것은 곧 컴포넌트의 재 렌더링을 유발한다. 또한, CheckIcon 컴포넌트 에서 React.memo를 활용한다 한들 4개의 props중 하나라도 다르다면 재 렌더링이 발생하기 때문에 React.memo의 성능을 제대로 활용할 수 없었다.
여기서 useDeferredValue를 활용한 이유는 bookName은 실시간으로 렌더링 되기 때문에 교재 제목 중복검사에 사용되는 상태 값을 우선순위가 낮은 작업으로 렌더링을 지연하기 위해서였다. 그리고 이를 통해 중복여부를 판단하도록 구현했다. 더 나아가 이렇게 구현하니까 불 필요한 API 호출도 방지할 수 있었다(교재 제목 중복검사 API).
그래서 수정한 로직은 다음과 같다. CheckIcon.jsx의 props로 우선순위가 낮은 deferredBookName, 그리고 isDuplicate 2개를 props로 보낸 뒤에 중복되지 않은 교재의 제목인 경우 iconVisible이라는 상태값을 이용하여 업데이트 하도록 구현했다. 그리고 결과적으로 타이핑을 빠르게 쳐도 재 렌더링은 발생하지 않고 타이핑이 끝난 뒤 API 호출을 통해 중복된 교재 제목인지를 판단하고 이후 체크 아이콘이 렌더링 되도록 문제를 해결할 수 있었다.


<깃허브 내역>
https://github.com/Kim-s-pirate/planner_client/commit/558e8a611aeea93a3de67f4891605caa54fd49ea
GitHub - Kim-s-pirate/planner_client
Contribute to Kim-s-pirate/planner_client development by creating an account on GitHub.
github.com