나는 인피니티 스크롤을 좋아한다
사용자일 때는 pagination을 좋아하지만 개발자로서는 인피니티 스크롤이 좋다
왜냐하면 pagination 컴포넌트 만드는 게 조금 귀찮다ㅋ,,,
는 거짓말이고
인피니트 스크롤 구현해 본 지 오래 돼서 해 봐야한다!
스크롤을 함에 따라 데이터가 불러와져 끝까지 다 불러와 질 때까지 계속해서 스크롤을 할 수 있게 되는 데이터 페칭 방식
-스크롤이 처음에는 짧았는데 어느 시점에 닿으면 길어짐

단점
// 기존 코드
export async function getProducts() {
const productQuerySnapShot = await getDocs(productCollection);
const products = [];
productQuerySnapShot.forEach((doc) => {
products.push(doc.data());
});
return products;
}
const productCollection = collection(db, "product");
const productQuery = query(productCollection, limit(limit), startAfter(startAfter))
const productQuerySnapShot = await getDocs(productQuery);
export async function getProducts({ limitValue, startAfterValue }) {
const productQuery = query(
productCollection,
orderBy("created_at", "asc"),
limit(limitValue),
startAfter(startAfterValue)
);
const productQuerySnapShot = await getDocs(productQuery);
const products = [];
productQuerySnapShot.forEach((doc) => {
products.push(doc.data());
});
const lastItem = productQuerySnapShot.docs[productQuerySnapShot.docs.length - 1];
return {
data: products,
startKey: lastItem,
};
}
// 다음 호출 시 사용할 startKey
let startKey = null;
async function addData() {
// 상품 3개씩 불러오기
// 저장된 startKey를 사용해 이전에 불러온 항목의 다음 항목부터 불러오기
const products = await getProducts({
limitValue: 3,
startAfterValue: startKey,
});
// 이번 호출로 넘어온 startKey 저장
startKey = products.startKey;
// 데이터를 추가할 element 참조
const adminMain = document.getElementById("admin");
const tableSection = adminMain.querySelector(".product-table__tbody");
// 테이블에 들어갈 데이터 컴포넌트 호출
const tableRow = products.data
.map((item) => {
return ProductTableRow(item);
})
.join("");
// 테이블에 삽입
tableSection.insertAdjacentHTML("beforeend", tableRow);
}
// 더 불러오기 버튼 클릭 시 위의 이벤트 발생
// 나중에는 스크롤이 끝에 닿을 때 발생하도록 함
const moreButton = document.getElementById("product-table-more-button");
moreButton.addEventListener("click", async () => {
await addData();
});

뷰포트를 기준으로 대상 요소에 변경이 있을 시에 비동기적으로 감지하는 수단
let intersectionObserver = new IntersectionObserver(callback)
intersectionObserver.observe(element)
<section class="infinity-scroll-area"></section>
const infinityScrollArea = document.querySelector('.infinity-scroll-area')
let intersectionObserver = new IntersectionObserver(async (e)=>{
if(e[0].isIntersecting && !!startKey){
await addData()
}
})
intersectionObserver.observe(infinityScrollArea)

상품 목록도 이렇게 구현하고 싶은데... 상품 ... 목록은 페이지 네이션 해야겠져...?