FrontEngineer JungBam

intersection Observer 기능 컴포넌트화하기 본문

개발일지

intersection Observer 기능 컴포넌트화하기

정밤톨 2023. 8. 31. 18:06
처음 무한스크롤을 구현한 1년 전보다 개념적으로도 실력적으로도 많이 늘었구나 싶다.

 react query의 useInfiniteQuery를 활용해서 무한스크롤을 만드는데에 있어 이전에는 불필요하게 파생상태들이 각각의 상태값으로 관리되어 불필요한 리렌더링을 가져왔고 이번에 만들때에는 그런 부분이 없도록 만드려고 노력했고 그 부분이 눈에 띄게 비교가 되어서 만족스럽다 ㅎㅎ
 그 중 fetchNextPage 함수를 실행시키기 위해서 intersection observer API 를 사용하기로 했다. 이 부분에서도 이전과는 달리 해당 UI 컴포넌트에 기능을 덕지덕지 붙이는 것이 아니라 로직만 별도 분리해서 컴포넌트로 만들었는데 깔끔하게 동작이 되어서 참 좋다. 만들면서 식별자도 신경을 많이 썼다. 누가봐도 알 수 있게.

onIntersect : 해당 target을 만났을 때에 동작하는 함수
canLoad : 해당 intersection observer의 위치를 재배정하는 시점
threshold : 교차가 발생하는 지점
import React from "react";

interface InfiniteScrollObserverProps {
  onIntersect: () => void;
  canLoad: boolean;
  threshold?: number;
  children: React.ReactNode;
}

const InfiniteScroll: React.FC<InfiniteScrollObserverProps> = ({
  onIntersect,
  canLoad,
  threshold = 0.7,
  children,
}) => {
  const loadMoreRef = React.useRef(null);

  React.useEffect(() => {
    const observer = new IntersectionObserver(
      (entries) => {
        const ob = entries[0];
        if (ob.isIntersecting && canLoad) {
          onIntersect();
        }
      },
      {
        threshold: threshold,
      },
    );
    if (loadMoreRef.current) {
      observer.observe(loadMoreRef.current);
    }
    return () => {
      if (loadMoreRef.current) {
        observer.unobserve(loadMoreRef.current);
      }
    };
  }, [canLoad]);

  return (
    <>
      {children}
      <div ref={loadMoreRef} />
    </>
  );
};

export default InfiniteScroll;
반응형
Comments