Intersection Observer(교차 관찰자 API)는 타겟 엘레멘트와 타겟의 부모 혹은 상위 엘레멘트의 뷰포트가 교차되는 부분을 비동기적으로 관찰하는 API이다.
즉, 화면 상에 내가 지정한 타겟 요소가 보이고 있는지를 관찰하는 API
<ListContainer>
{items.map((item: IlistWithMemo, index: number) => (
<React.Fragment key={index}>
{items.length - 1 === index ? (
<div ref={setTarget}>
<ListCard
key={index}
data={item}
setOpenModal={setOpenModal}
setClickedItem={setClickedItem}
/>
</div>
) : (
<div>
<ListCard
key={index}
data={item}
setOpenModal={setOpenModal}
setClickedItem={setClickedItem}
/>
</div>
)}
</React.Fragment>
))}
</ListContainer>
"items 길이-1" 이 인덱스와 같다면 마지막 아이템이므로 ref={setTarget} 적용해서 관찰대상 생성
2. new IntersectionObserver(callback, options)로 관찰자 객체를 생성 -> 생성한 관찰자는 관찰 대상을 관찰함!
3. 관찰 대상이 지정한 옵션을 만족하는 상태에 놓이게 되면 콜백 함수 실행
const options = {
root: null,
rootMargin: '0px',
threshold: 1,
};
useEffect(() => {
if (!setTarget.current) return;
const observer = new IntersectionObserver(callback, options);
observer.observe(setTarget.current);
return () => observer.disconnect();
}, [options, setTarget]);
const callback = (entry) => {
if (entry.isIntersecting && !loadFinished) setPage(page + 1);
};
스크롤을 내리면서 관찰 대상을 만나고 조건을 만족시키면 콜백함수를 실행하고 새로운 데이터를 가져오게 된다.
이때 observer.disconnect();로 관찰 대상을 지워주고 다시 스크롤을 내렸을 때 관찰 대상이 새롭게 만들어지도록 해야함
npm i react-intersection-observer
const [ref, inView] = useInView();
<ListContainer>
{items.map((item: IlistWithMemo, index: number) => (
<React.Fragment key={index}>
{items.length - 1 === index ? (
<div ref={ref}>
<ListCard/>
</div>
) : (
<div>
<ListCard />
</div>
)}
</React.Fragment>
))}
</ListContainer>
ref 를 div에 걸어주면 해당 요소가 보이면 inView가 true 로, 안 보이면 false로 자동으로 변경된다.
받아온 "items 길이-1" 이 인덱스와 같다면 마지막 아이템이므로 inView를 true로 변경하여 useEffect 실행하여 데이터를 받아올 수 있도록 구현
useEffect(() => {
if (inView && !loading && !loadFinished) {
setPage((prev) => prev + 1);
}
}, [inView, loading, loadFinished]);
https://nohack.tistory.com/124 [lucid_dream]
https://simian114.gitbook.io/blog/undefined/react/intersectionobserverapi
https://slog.website/post/8