packagesreacthooksuseIntersectionObserver

useIntersectionObserver

Intersection Observer API를 사용하여 요소의 가시성 변화를 관찰하는 Hook입니다. 무한 스크롤, 이미지 레이지 로딩 등에 유용합니다.

Props

이름타입설명기본값
rootElement | null가시성을 확인할 뷰포트 요소, 뷰포트를 지정하지 않을 경우 브라우저의 뷰포트를 사용합니다.null
rootMarginstring루트 요소의 마진'0px'
thresholdnumber | number[]콜백 실행 시점의 가시성 퍼센티지 (0~1)0
onChange(entry: IntersectionObserverEntry) => void가시성 변경 시 호출되는 콜백-
onEnter() => void요소가 뷰포트에 진입 시 호출되는 콜백-
onLeave() => void요소가 뷰포트에서 벗어날 때 호출되는 콜백-
unobserveOnEnterboolean진입 후 관찰 중지 여부false
unobserveOnLeaveboolean관측된 후 뷰포트에서 벗어날 때 관찰 중지 여부false

Return

  • ref: 관찰할 요소에 연결할 ref 객체
  • observe: 관찰 시작 함수
  • unobserve: 관찰 중지 함수

Usage

import { useIntersectionObserver } from '@teamsparta/react';
 
function Example() {
  const { ref } = useIntersectionObserver({
    onEnter: () => console.log('요소가 화면에 나타남'),
    onLeave: () => console.log('요소가 화면에서 사라짐'),
  });
 
  return <div ref={ref}>관찰할 요소</div>;
}

Example

무한 스크롤

function InfiniteScroll() {
  const [items, setItems] = useState<string[]>([]);
  const [isLoading, setIsLoading] = useState(false);
 
  const { ref } = useIntersectionObserver({
    onEnter: async () => {
      if (isLoading) return;
 
      setIsLoading(true);
      const newItems = await fetchMoreItems();
      setItems((prev) => [...prev, ...newItems]);
      setIsLoading(false);
    },
  });
 
  return (
    <div>
      {items.map((item) => (
        <div key={item}>{item}</div>
      ))}
      <div ref={ref}>{isLoading ? '로딩 중...' : '더 보기'}</div>
    </div>
  );
}