본문 바로가기

TIL

React lodash debounce

  const debouncedSearch = debounce(keyword => {
    console.log('debounce');
    if (keyword === '') return;
    fetcher(`${API.search_movie}?q=${keyword}`).then(
      ({ data }) => data.message === 'SUCCESS' && setMovieList(data.result)
    );
  }, 3000);
  
  <TextField
    onChange={e => {
      setSearch(e.target.value);
      debouncedSearch(e.target.value);
    }}
  />

기다렸다가 몰아서 다 실행된다. 네트워크 탭을 보면 pending이었다가 요청이 완료된다. 그냥 속도가 느린 것 같다.

 

https://rajeshnaroth.medium.com/using-throttle-and-debounce-in-a-react-function-component-5489fc3461b3 

This is a caveat of function components. Local variables inside a function expires after every call. Every time the component is re-evaluated, the local variables gets initialized again.
Throttle and debounce works using window.setTimeout() behind the scenes. Every time the function component is evaluated, you are registering a fresh setTimeout callback.

 

useRef

디바운스된 콜백에 대한 참조를 보관해야 함. useRef()는 멤버 변수와 동등하다고 함. useRef가 반환한 값은 함수 컴포넌트가 실행될 때마다 다시 평가되지 않음. 그래서 이 상황의 해결책이 될 수 있음.

한가지 단점은 .current를 해서 저장된 값에 접근할 수 있다는 것.

  const delayedQuery = useRef(_.debounce(q => sendQuery(q), 500)).current;

 

useCallback

useRef 단점 해결. 가장 적절한 솔루션일 듯.

const delayedQuery = useCallback(_.debounce(q => sendQuery(q), 500), []);
근데 왜인지 알아봐야 하는 게, "React Hook useCallback received a function whose dependencies are unknown. Pass an inline function instead."라고 떠서 다음과 같이 하면 동작하지 않는다.
const delayedQuery = useCallback(()=>_.debounce(q => sendQuery(q), 500), []);​

useCallback 문법과 debounce 함수 구조를 살펴봐야 할 것 같다.

 

'TIL' 카테고리의 다른 글

axios, swr, React 네트워크 통신  (0) 2022.12.19
python 서버 켜기  (0) 2022.11.03
React 쿼리 파라미터 값  (0) 2022.09.07
CSS img object-fit  (0) 2022.08.24
alert 말고 window.confirm  (0) 2022.08.09