rhanziy

React Native - useDeferredValue로 추천 검색 리스트 노출하기(feat.debounce) 본문

React Native

React Native - useDeferredValue로 추천 검색 리스트 노출하기(feat.debounce)

rhanziy 2024. 4. 25. 13:47

 

예시이미지 ㅋ

검색 서치바에 키워드를 입력하면 등록된 상품 중, 해당 키워드가 include되어있으면 리스트에 노출하는 기능을 구현했었다.

보통 이런 경우에 사용자가 input에 입력하거나 지울때마다 키워드가 있는지 없는지 비교를 하는데, 과도한 요청 및 처리를 수행하게 될 경우 발생할 수 있는 성능 저하를 막기 위해 연속적으로 호출되는 함수 중 마지막 함수만 호출하는 debounce 기법을 사용하여 제어한다.

 

기존 구현했던 방식은 setTimeout을 이용해서 키워드 입력 후 일정 지연시간 후에 리스트를 노출해주었었다.

  const [inputKeyword, setInputKeyword] = useState<string>(keyword ?? '');

  useEffect(() => {
    const debounce = setTimeout(() => {
      if (inputKeyword) {
        // ...생략
      }
    }, 500);
    return () => {
      clearTimeout(debounce);
    };
  }, [inputKeyword, ]);

 

하지만 공식문서를 보다보니 React 18에서 concurrent rendering을 위해 새로 나온 useDeferredValue 라는 Hook이 있어서 정독하던 중, 어 이거 대체할수있겠다~ 싶어서 적용해보았음!

 

기존코드의 문제점

1. 사용자의 장치 기능성에 상관없이 무조건 debounce를 위한 고정 지연시간이 있는 점

2. 렌더링을 하던 중 키 입력 이벤트가 발생했을때, 버벅이는 현상이 발생할 수 있는 점

useDeferredValue

값의 업데이트 우선순위를 제어할 수 있다. 주로 낮은 우선순위를 지정하기 위한 훅이다. 우선순위가 높은 작업을 실행하는 동안 useMemo와 유사하게 이전 값을 계속 들고 있으면서 업데이트를 지연시킨다.

debouncing과의 차이점은 자체적으로 고정적인 지연 값에 의해 실행되는게 아니고, 새로운 처리를 위해 지연된 렌더링이 중단될 수 있다는 점이다. 즉, react가 비용이 큰 목록을 렌더링하는 중 사용자의 새로운 요청이 들어오면 수행하던 렌더링을 포기하고 사용자 이벤트를 먼저 처리한 다음 백그라운드에서 다시 렌더링을 시작한다. 유저에게 좋은 경험을 줄 수 있다는 장점!

  const [inputKeyword, setInputKeyword] = useState<string>(keyword ?? '');
  const deferredKeyword = useDeferredValue(inputKeyword);
  
  {deferredKeyword !== '' &&  (
    <SearchingScreen inputKeyword={deferredKeyword} />
  )}

 

사용법 쏘 이지.

inputKeyword를 useDeferredValue에 담아 변수를 지정해주고, defferedKeyword가 공백이 아니면 추천검색 리스트를 보여준다.

비용이 많이드는 계산은 useMemo와 함께 의존성 배열에 deferredValue를 넣어 사용하면 효율이 좋다고 한다.! 하지만 내 검색리스트는 구현이 간단해서 사용안함ㅋㅎ

그리고 이제 <Suspense>와 통합되어, useDeferredValue 훅을 통해 로딩화면을 구현할 수 있다.

 


비슷한 개념의 useTransition

[isPending, startTransition] 을 반환하며, isPending 은 작업이 지연되고 있음을 알리는 boolean 이며, startTransition 은 낮은 우선순위로 실행할 함수를 인자로 받는다.
useTransition은 함수 실행의 우선순위를 지정하는 반면, useDeferredValue는 값의 업데이트 우선순위를 지정한다는 차이가 있다.

Comments