프리온보딩 코스 과제 1 - 무한스크롤 구현
많은 데이터를 하나의 페이지에 렌더링할 때 지연 로딩을 하는 방식 중 하나. 페이스북, 인스타그램 등에서 사용. 콘텐츠가 없을 때까지 계속해서 스크롤을 늘려 가면서 새로운 콘텐츠를 덧붙여서 렌더링한다.
사용자가 scroll을 할 때 이벤트가 발생하고, 현재 scroll 위치를 파악하여 페이지 끝에 도달했다면 새로운 콘텐츠를 요청하는 방식. scroll event는 매우 빈번하게 발생하기 때문에 이 방법을 사용하면 애플리케이션 전체의 성능이 저하될 수 있다.
DOM element 간의 교차 영역에서 발생하는 변경 사항을 '비동기적으로' 감시할 수 있어서 퍼포먼스가 좋다. 익스플로러😨 이외의 브라우저들은 거의 지원한다. Intersection 외에도 자바스크립트가 지원하는 Observer API에는 MutationObserver, ResizeObserver 등이 있다.
Intersection Observer를 더 자세히 알아보자.
const observer = new IntersectionObserver(callback, option {
root: (default: null),
rootMargin: (default: '0px'),
threshold: (defalut: 0) // 0.0 ~1.0 사이의 숫자나 배열 값.
})
parameter는 callback함수와 option
ex) 파란 박스가 root, 빨간 박스가 관측 대상, threshold가 0.5인 경우
const InfiniteScrollList = () => {
const [commentList, setCommentList] = useState([]);
const [pageNumber, setPageNumber] = useState(1);
const [isLoading, setIsLoading] = useState(true);
const [hasMore, setHasMore] = useState(true);
const loader = useRef(null);
const PAGE_LIMIT = 50;
const getCommentList = () => {
setIsLoading(true);
axios
.get(`https://.../comments?_page=${pageNumber}&_limit=10`)
.then(response => {
setIsLoading(false);
setCommentList(items => [...items, ...response.data]);
setHasMore(pageNumber !== PAGE_LIMIT);
})
.catch(error => console.warn(error));
};
useEffect(() => {
getCommentList();
}, [pageNumber]);
const onIntersect = entries => {
entries.forEach(element => {
if (element.isIntersecting && hasMore) {
setPageNumber(prev => prev + 1);
}
});
};
useEffect(() => {
const options = {
root: null,
rootMargin: "0px",
threshold: 0,
};
const observer = new IntersectionObserver(onIntersect, options);
observer.observe(loader.current);
return () => observer.disconnect();
}, [loader]);
return (
<div className="content-container">
{commentList.map(item => (
<CommentCard key={item.id} item={item} />
))}
<div ref={loader} className="loader">
{isLoading && "Loading..."}
</div>
</div>
);
};
export default InfiniteScrollList;
주의하겠습니다.....