디바운싱을 실무에 적용하다

Kyung·2023년 4월 23일
0

적용 동기

  • Table UI에서 focus된 row의 댓글 정보를 보여주는 기능을 구현하는데 적용하였다.
  • 구현된 table UI에서 rows를 키보드 UP/DOWN 키로 순회가 가능하였기 때문에 focus가 바뀔 때마다 댓글 정보를 fetch하는 로직을 짜게 되면 불필요한 요청이 많이 발생될 것이 우려되었다.
    • 예를 들어 키보드를 이용하여 1번 row에서 30번 row로 이동하게 되면 row가 30번 바뀌므로 30번의 요청을 하게된다.
  • 일정 시간 동안 여러 이벤트가 발생했을 때 가장 마지막 이벤트만을 발생시키는 기술인 디바운싱을 적용한다면 이 문제를 우아하게 해결할 수 있을 것이라고 판단하였다.

구현 코드

useDebounce

import { useEffect, useState } from 'react';

const useDebounce = <T>(value: T, delay?: number): T => {
	const [debouncedValue, setDebouncedValue] = useState<T>(value);

	useEffect(() => {
		const timer = setTimeout(() => setDebouncedValue(value), delay || 500);
		return () => {
			clearTimeout(timer)
		}
	}, [value, delay]);

	return debouncedValue;
}

export default useDebounce;
  • 첫번째 파라미터는 디바운싱를 적용할 값을, 두번째 파라미터는 디바운싱 시간을 넣어준다.
    • 두번째 파라미터로 들어오는 delay의 경우, 상황에 따라 알맞게 조절해준다.
  • 만약 useDebounce(value)라고 작성한다면, value값이 0.5초 동안 대기했다가 만약 이 사이에 값이 바뀌었다면 다시 0.5초를 대기하고, 값이 그대로라면 setDeboundedValue를 하여 state를 변경시킨다.
  • useDebounce의 반환값으로 debouncedValue를 반환한다.
  • value가 1 -> 2 -> 3 -> 4으로 변경되고 value가 1 -> 2 -> 3 -> 4으로 변화하는 간격이 0.5초 이내라면 디바운싱을 적용하여 값이 1 -> 4로만 바뀌도록 값을 만들 수 있다.
  • value가 useState의 초기값으로 들어가는데, value가 바뀐다고 state가 바뀌지 않는다.

리액트 쿼리와 결합

const debouncedId = useDebounce(selectedRowId);
const { data, isLoading } = useQuery(['comment', debouncedId], () => getComment(debouncedId));
  • 이런 구현을 통해서 만약 키보드를 이용하여 1번 row에서 30번 row로 이동하게 된다면 row가 30번 바뀌더라도 1번의 요청을 하게된다.
profile
개발 일지를 작성합니다

0개의 댓글