프론트엔드/React.js

useDeferredValue를 활용한 교재 제목 중복검사 API 연동

Jay_Jung 2024. 11. 30. 15:26


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

교재를 추가하는 LibraryAddModal.jsx

 

교재 이름을 타이핑 할 때 중복되면 뜨는 문구

 

교재 이름을 타이핑 할 때 중복이 안되면 뜨는 문구

 
 
해당 기능을 구현하는 과정에서 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를 보내는 기존의 로직

 
 

기존의 CheckIcon 컴포넌트

 
코드를 보면 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 호출을 통해 중복된 교재 제목인지를 판단하고 이후 체크 아이콘이 렌더링 되도록 문제를 해결할 수 있었다.
 

CheckIcon 컴포넌트로 2개의 props를 보내는 현재의 로직

 

2개의 props를 기반으로 iconVisible이라는 상태값을 업데이트 시키기

 
 

<깃허브 내역>

 
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