Intersection Observer API는 뷰포트와 특정 요소의 교차점 (intersection)을 관찰하는 (observe) 하는 API로 스크롤 리스너를 등록함으로써 일어날 수 있는 불필요한 이벤트 호출을 최소화하기 때문에 랜더링 성능 측면에서도 우위를 점할 수 있습니다.
이렇게 데이터의 마지막 리스트 부분이 화면에서 잡히면 로딩이 풀리는 모습으로 나오게 됨.
고민을 했을때 생각해봤는데 기존에 데이터 일부가 보여지고 화면(뷰포트)에서 지정시킨 element가 교차해서 지나갈때 데이터가 추가가 되는것을 고려하여 데이터를
받아올때, 나는 데이터를 받아오는 함수가 전체로 받아오기에 페이지화를 해서 받아와야겠다. 생각해서 추가로 화면엔 일부만 데이터를 보여주면서 스크롤이 될수록 추가로 계속해서 받아오게끔 하는 방법으로 만들었다.
무한 스크롤을 사용시에 Intersection Observer API 라는 방법과 라이브러리를 사용하는 방법이 있었고
전에 강의에서 배웠던 react-intersetcion-observer라는 라이브러리를 사용.
기존에 데이터를 받아오는 방식이 파이어베이스이기에, 데이터를 원하는 갯수만큼 받아오고, 마지막 데이터를 알수있는 적합한 메서드가 있는지 찾아봤고, startAfter라는 메서드가 있었고, 이것은 페이지화를 하는데 있어서 가장 중요한 메서드다.
// 추가로 데이터 불러오기
const loadMore = useCallback(
async (loadCount: number) => {
const queryRef = query(
collection(dbService, collectionName),
orderBy('id', 'asc'),
limit(loadCount),
startAfter(key), // 이 메서드가 가장 중요햇음
);
try {
const snap: any = await getDocs(queryRef);
setTimeout(() => {
snap.empty === 0 ? setNoMore(true) : setKey(snap.docs[snap.docs.length - 1]);
const docsArray = snap.docs.map((doc: any) => ({
id: doc.id,
...doc.data(),
}));
setList([...list, ...docsArray]);
}, 1000);
} catch (err) {
console.log(err);
}
},
[collectionName, list, key],
);
그리고 나서
React-Intersection-observer라는 라이브러리로,
useInView를 사용하여
useEffect(() => {
if (inView) {
loadMore(7);
}
}, [inView]);
view안에 들어오면 데이터를 불러오게끔