프로젝트에서 견적 요청 값에 따른 자동 계산식을 보여줘야 되는 기능을 만들게 되었다.
사용자가 선택한 여러 옵션값들을 종합하여, 자동으로 계산된 값을 보여줘야 했다.
input으로 값을 받을 때, onChange 값이 바뀔 때마다 api를 전송한다면(위 사진 참고) 쓸모없는 api 요청이 발생하여, 웹 성능이 저하될 것이다.
예를 들어 유저가 수량 input에 숫자 100을 입력하려고 할 때, 디바운싱을 적용하지 않는다면
- 1
- 10
- 100
api가 3번이나 호출되고 나서야 원하는 값을 줄 수 있을 것이다.
디바운싱은 연이어 호출되는 함수들 중 마지막 함수만 호출하는 것을 말한다.
나는 특정 서비스 상에 구현되어 자동 계산식이라는 한정된 용어를 사용했지만, 기본적으로 검색 기능을 구현할 때 사용한다고 보면 된다.
디바운싱을 사용하여 위와 같이 3번의 과정을 거쳐 100을 호출하는 것이 아닌, 유저가 값(100)을 입력하고 일정시간 동안 더 이상 값을 입력하지 않을 때 api를 호출하도록 만들어줄 것이다.
useDebounce
import { useEffect, useState } from "react";
function useDebounce<T>(value: T, delay = 500): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value);
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(timer);
};
}, [value, delay]);
return debouncedValue;
}
export default useDebounce;
나는 다른 컴포넌트에서 재사용이 가능한 커스텀 훅, useDebounce을 만들어 디바운싱을 구현했다.
useState을 사용하여 디바운스된디바운스 된 값을 저장하고, useEffect을 사용하여 딜레이 시간이 경과했을 때, 입력된 값을 디바운스 된 값으로 업데이트해 준다.
이때, 이전에 실행된 Timer를 제거하기 위해 clearTimeout을 사용해 준다.
setTimeout함수는 타이머 ID를 반환하는데, 이 타이머 ID를 clearTimeout함수로 제거하지 않으면 이전에 생성된 타이머가 계속돼서 실행되기 때문에 메모리 누수(memory leak)가 발생하기 때문이다.
마무리하며
평소에 이론적으로만 알던 개념을 실무에서 서비스 내에 실제로 적용하게 되어 뿌듯했다.
단순히 굴러가는 웹 화면을 만드는 것이 아닌 잘 만든 웹사이트를 만들고 싶다는 생각이 더욱더 들게 되었다 :)
'Front-end > React' 카테고리의 다른 글
[Next] dayjs UTC시간 -> 현지시간 적용 (0) | 2023.07.21 |
---|---|
[React] 타이머 구현하기 (0) | 2023.05.07 |
[React] hooks로 모듈화하여 변경에 유연한 컴포넌트 만들기 (0) | 2023.02.11 |
[React] Proxy 설정하기 (0) | 2022.09.29 |
[Next] create-next-app 분석하기 (0) | 2022.08.14 |