InView
Intersection Observer API를 사용하여 요소의 뷰포트 가시성을 감지하는 컴포넌트입니다.
Props
이름 | 타입 | 설명 | 기본값 |
---|---|---|---|
children | ReactElement | ReactElement[] | 관찰할 자식 요소 | - |
root | Element | null | 가시성을 확인할 때 사용할 뷰포트 요소 | null |
rootMargin | string | 루트 요소의 마진 | "0px" |
threshold | number | number[] | 콜백 실행 시점의 가시성 비율 | 0 |
onChange | (entry: IntersectionObserverEntry) => void | 가시성 변경 시 호출될 콜백 | - |
onEnter | (entry: IntersectionObserverEntry) => void | 요소가 뷰포트에 진입 시 호출될 콜백 | - |
onLeave | (entry: IntersectionObserverEntry) => void | 요소가 뷰포트에서 벗어날 때 호출될 콜백 | - |
unobserveOnEnter | boolean | 진입 후 관찰 중단 여부 | false |
unobserveOnLeave | boolean | 이탈 후 관찰 중단 여부 | false |
사용 예시
기본 사용법
function Example() {
return (
<InView onEnter={() => console.log('요소가 보입니다')}>
<div>관찰할 컨텐츠</div>
</InView>
);
}
무한 스크롤
function InfiniteScroll() {
const [items, setItems] = useState([]);
const loadMore = () => {
// 추가 데이터 로드 로직
};
return (
<div>
{items.map((item) => (
<Item key={item.id} {...item} />
))}
<InView onEnter={loadMore}>
<div>로딩 중...</div>
</InView>
</div>
);
}
지연 로딩
function LazyImage() {
const [isLoaded, setIsLoaded] = useState(false);
return (
<InView onEnter={() => setIsLoaded(true)} unobserveOnEnter>
{isLoaded ? (
<img src="heavy-image.jpg" alt="지연 로딩된 이미지" />
) : (
<div>로딩 중...</div>
)}
</InView>
);
}
커스텀 옵션 사용
function CustomExample() {
return (
<InView
threshold={[0, 0.5, 1]}
rootMargin="10px"
onChange={(entry) => {
console.log('가시성:', entry.intersectionRatio);
}}
>
<div>상세한 관찰이 필요한 컨텐츠</div>
</InView>
);
}
주의사항
- 단일 자식 요소는
forwardRef
를 사용하여 ref를 전달받을 수 있어야 합니다. - 여러 자식 요소가 있을 경우 자동으로 div로 감싸집니다.
- 자식 요소는 최소 하나 이상 필요합니다.
- 브라우저가 Intersection Observer API를 지원해야 합니다.