여행자모드에서 여행자가 신청한 여행에 대한 리스트를 서버에서 불러오는데, 신청 개수에 제한이 없기 때문에 불러올 리스트가 많아지면 첫 렌더링을 할 때 시간이 오래 걸릴 수 있다는 단점이 있었다.
그래서 불러오는 리스트 아이템의 개수를 제한해주는 기능이 필요했는데, 페이지네이션과 무한스크롤 그리고 더보기버튼 중에서 불필요한 클릭을 없애고, 페이지 로딩속도가 빠른 무한스크롤로 구현하기로 했다.
사용자가 페이지 하단에 도달하면, 콘텐츠가 계속 로드되게 하는 사용자 경험을 말한다. 무한스크롤의 구현 방법은 대표적으로 스크롤이벤트가 있는데 스크롤이벤트는 reflow가 계속되고, 호출수 제한을 위해 debounce와 throttle을 따로 사용해주어야 한다는 단점이 있다.
그래서 나는 별도의 호출수 제한이 필요 없고, node를 관찰하게 하는 intersection observer를 사용해서 구현해줬다.
IntersectionObserver 인터페이스는 대상 요소와 그 상위 요소 혹은 최상위 도큐먼트인 viewport와의 교차 영역에 대한 변화를 비동기적으로 감지할 수 있도록 도와준다.
intersection observer 생성자는 두개의 인수를 갖는데, 하나는 callback함수이고, 하나는 options이다. new 키워드로 intersection observer의 인스턴스를 생성하면, 관찰자(observer)를 초기화하고 관찰 대상(element)를 지정할 수 있다.
const observer = new intersectionObserver(callback, options) //observer초기화
observer.observe(element) //관찰대상 등록
**callback**
관찰할 대상이 설정되거나 가시성에 변화가 생기면 실행되는 함수이다. callback은 entries, observer 두개의 인자를 가진다.
const observer = new intersectionObserver((entries, observer) => {}, options)
**options**
options는 intersection observer의 위치나, 얼만큼 교차되어야 이벤트가 발생하는지 등의 정보를 담은 객체이다.
const observer = (node) => {
if (isLoading) return;
if (observerRef.current) observerRef.current.disconnect();
observerRef.current = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting && hasMore && isActive.approved) {
setPageNum({ ...pageNum, approved: pageNum.approved + 1, completed: 1 });
} else if (entry.isIntersecting && hasMore && isActive.completed) {
setPageNum({ ...pageNum, completed: pageNum.completed + 1, approved: 1 });
}
},
{ rootMargin: '700px 0px 10px 0px', threshold: 0.3 }
);
node && observerRef.current.observe(node);
};