React Query의 Infinite scroll
: 무한 스크롤을 지원하고, 화면 스크롤을 통해 추가 데이터를 자동으로 로드할 수 있는 강력한 기능 제공
• data: Infinite Query 결과 데이터
• data.pages: 가져온 페이지들의 배열
• data.pageParams: 페이지를 가져오기 위한 페이지 매개 변수. 배열의 형태.
• fetchNextPage, fetchPreviousPage: 다음 페이지 및 이전 페이지의 데이터를 가져오는 함수
• getNextPageParam, getPreviousPageParam: 다음 및 이전 페이지에 대한 매개 변수를 생성하는 함수
• hasNextPage, hasPreviousPage: 다음 페이지 및 이전 페이지가 있는지 여부를 나타내는 불리언 값
• isFetchingNextPage, isFetchingPreviousPage: 다음 페이지 또는 이전 페이지의 데이터를 가져오는 동안 로딩 상태를 나타내는 불리언 값
Javascript의 scroll 이벤트의 한계점
• Javascript에서 무한 스크롤 구현 방법: addEventListener()에 scroll 이벤트 이용해서 구현
• 또한, getBoundingClientRect() 메서드로 원하는 특정 위치에서 다음 페이지들을 가져오도록 구현
// 빈 리스트 선택
const listElem = document.querySelector('#infinite-list')
// 20개의 아이템 추가 함수
let nextItem = 1
const loadMore = function () {
for(let i = 0; i < 20; i++) {
let item = document.creatElement('li')
item.innerText = 'List Item #' + nextItem++
listelm.appendChild(item)
}
}
// ul 리스트 바닥까지 스크롤 했는지 확인
listElm.addEventListener('scroll', function () {
if (listElm.scrollTop + listElm.clientHeight >= listElm.scrollHeight) {
loadMore()
}
})
// 아이템 20개씩 더 가져오는 loadMore 함수 실행
loadMore()
• 하지만, 위 코드는 성능 문제를 발생시킴.
• scroll 이벤트: 단시간에 수백번 호출이 되며 동 기적으로 실행
• getBoundingClientRect 메서드: 계산을 할 때 마다 리플로우 현상이 일어남
• 해결방안: Intersection Observer를 사용해 비동기적으로 교차점 관찰
Intersection Observer
: 브라우저 viewport와 원하는 요소의 교차점을 관찰하며, 요소가 뷰포트에 포함되는지 아닌지 구별하는 기능
// IntersectionObserver 등록
const io = new IntersectionObserver(entries => {
enties.forEach(entry => {
// 관찰 대상이 viewport 안에 들어온 경우 'active' 클래스 추가
if (entry.interSectionRatio > 0) {
entry.target.classList.add('active')
}
// 그 외의 경우 'active' 클래스 제거
else {
entry.target.classList.remove('active')
}
})
})
// 관찰할 대상을 선언하고, 해당 속성을 관찰
const boxList = document.querySelectorAll('.box')
boxList.forEach(el => {
io.observer(el)
})
• 비동기적으로 실행되기 때문에, 메인 스레드에 영향을 주지 않으면서 요소들의 변경사항 관찰
• Scroll 및 getBoundingClientRect의 성능 문제를 해결
• 또한, IntersectionObserverEntry 등의 속성을 활용해서 요소들의 위치를 알 수 있음
Intersection Observer 기본 문법
• Intersection Observer API는 다음과 같은 상황에 콜백 함수를 호출:
(1) 대상(target) 요소가 기기 뷰포트나 특정 요소(이 API에서 이를 root 요소 혹은 root로 칭함)와 교차할 때
(2) 관찰자(observer)가 최초로 타겟을 관측하도록 요청받을 때
// observer 초기화
let io = new Intersection Observer(callback, options)
iio.observer(element) // 관찰 대상 등록
• IntersectionObserver() 생성자는 2개의 인수 (callback, options)를 갖는다.
• callback: 관찰할 대상 (target)이 등록되거나, 가시성에 변화가 생기면 실행. 두 개의 인수 (entries,
observer)를 갖는다.
• Options: 관찰이 시작되는 상황에 대한 옵션을 설정할 수 있음 (root, rootMargin, threshold)
Intersection Observer Callback: Entry 속성
• IntersectionObserverEntry는 읽기 전용의 여러가지 속성들을 포함
• boundingClientRect: 관찰 대상의 경계 사각형을 DOMRectReadOnly로 반환
• intersectionRect: 관찰 대상의 교차한 영역 정보를 DOMRectReadOnly로 반환
• intersectionRatio: 관찰 대상의 교차한 영역의 비율을 0.0과 1.0 사이의 숫자로 반환
• isIntersecting: 관찰 대상이 교차 상태인지 아닌지 반환(Boolean)
• rootBounds: 지정한 루트 요소의 사각형 정보를 DOMRectReadOnly로 반환
• target: 관찰 대상 요소(Element) 반환
• time: 변경이 발생한 시간 정보(DOMHighResTimeStamp) 반환
Intersection Observer Options
• Intersection Observer는 Options를 통해 관찰이 시작되는 상황에 대한 옵션을 설정할 수 있음
• root: 대상 객체(target)의 가시성을 확인할 때 사용되는 뷰포트 요소
• rootMargin: root 가 가진 바깥 여백(Margin). margin 값을 이용해 root 범위를 확장 / 축소할 수 있음
• Ex) “10px 20px 30px 40px” (top, right, bottom, left). 기본값은 0
• threshold: observer의 콜백이 실행될 대상 요소(target)의 가시성이 얼마나 필요한지 나타내는 값
Intersection Observer 메서드
• observe: 대상 요소 (target)의 관찰을 시작할 때 사용
• unobserve: 대상 요소의 관찰을 중지할 때 사용. 관찰을 중지할 하나의 대상 요소를 인수로 지정해야 함
• disconnect: IntersectionObserver 인스턴스가 관찰하는 모든 요소의 관찰을 중지할 때 사용
실제 구현 코드
https://github.com/yejify/food-app/commit/4be332927d91df9960360d2e9ce62476b99d0afe
'2024 > 프로젝트' 카테고리의 다른 글
[food-app] next.js에서 getStaticProps 사용 하다가 마주친 에러 (0) | 2024.10.07 |
---|---|
[My Little Rosemary] vanilla-extract 기본 세팅하기 (0) | 2024.07.28 |
[My Little Rosemary] Next.js에서 어떤 도구로 스타일링 해야 될까? (1) | 2024.07.17 |
[My Little Rosemary] 프로젝트의 시작은 역시 기획이지 (1) | 2024.06.11 |
[Wiki Page] typescript에서 만난 오류 디버깅 (0) | 2024.04.07 |