[FE] debounce 를 위한 lodash와 hook

쭈리·2024년 5월 9일

FE

목록 보기
9/10

Debounce 란?


우리가 검색 인풋에 단어를 입력하면 입력되는 글자가 변경됨에 따라 값 변경 함수가 계속해서 호출되게 된다. 이렇게 잦은 값 변경이 일어나거나 혹은 연결된 API가 있는 경우 불필요한 렌더링 등으로 성능 저하가 일어나기 쉽다. 그래서 값 변경 사이에 일정한 시간 텀을 두어 연속적인 이벤트 발생을 하나로 처리하는 방식이 debounce 방식이다.

직접 debounce 함수 만들기

상품을 검색하는 input을 만들었다. 이 때 onChange에 따라 감지되는 모든 값을 함수에 전달하는 코드를 쓰게 되면 불필요한 렌더링이 많이 일어나게 된다.


이렇게 모든 입력이 감지되기 때문이다. 그래서 setTimeout을 사용해서 debounce 함수를 만들었다.

import { useEffect, useState } from "react";

export const useDebounce = (value: string, dealy = 100) => {
  const [valueState, setValueState] = useState<string>(value);

  useEffect(() => {
    let timeout = setTimeout(() => {
      setValueState(value);
    }, dealy);
    return () => {
      clearTimeout(timeout);
    };
  }, [value, dealy]);
  return valueState;
};

이 debounce 함수를 hook 으로 만들어서 컴포넌트에 불러와 사용해줬다.

  const [textVal, setTextVal] = useState<string>(searchVal || "");

  // hook 을 useDebounce로 호출해서 사용
  const debouncedText = useDebounce(textVal, 300);

  useEffect(() => {
    // 입력된 textVal 값을 검색할 때 debounce 적용해서 setInput으로 넘기기
    setInput(debouncedText);
  }, [debouncedText, setInput]);

  const handleTextChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setTextVal(() => e.target.value);
  };

  // 중략

  return (
    <input
      placeholder={placeholder}
      onChange={handleTextChange}
      onKeyDown={handleEnterKey}
      value={textVal}
      autoFocus={focus}
    />
  );

이렇게 코드를 작성해서 300 인터벌 타임을 준 결과,

이렇게 확연한 차이를 보였다. (조금 원활한 검색을 위해 100으로 사용했다.)

Lodash 사용하기

javascript에서 debounce를 사용할 때 유용한 라이브러리 중 하나가 Lodash 이다. 사실 평소에 라이브러리 검색을 잘 하지 않고 직접 만들어보는 편이라 있는 줄 몰랐는데, 면접 때 Lodash를 왜 사용하지 않았는지 물어봐주셔서 알게 되었다.

👉 Lodash 공식 문서 바로가기

# npm 설치하기
npm i --save lodash
import debounce from "lodash/debounce";

const debouncedText = useCallback(
  debounce((q) => setInput(q), 300),
  []
);

const handleTextChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  setTextVal(() => e.target.value);
  // 타이핑 끝나면 호출함
  debouncedText(e.target.value)
};

정리

이벤트가 끝나고 함수를 실행하는 debounce와 달리 이벤트 실행 후 일정 시간을 기다려서 함수를 한 번만 작동하게 하는 throttle이 있다. 이전에 프로젝트를 하면서 버튼 클릭 후 api 응답이 오기 전에 버튼을 계속 눌러서 계속 api를 호출하는 문제가 있었는데, 이 경우를 해결할 수 있는 방법을 알게되어 수정해볼 수 있을 것 같다.

profile
화면 아래에 논리를 펼치는 프론트엔드 엔지니어 🐥

0개의 댓글