728x90
반응형
이리뛰랴 저리뛰랴 바빴던 오늘
딱히 뭐 한게 없는데 하루가 왜 다.. 가버렸지?
여튼 오늘은 실습하기 전.. 간단하게 강의정리좀 해보겠습니다
가보자고.
챌린지반 강의정리 - 페이지네이션, 무한스끄롤
아, 이게 페이지네이션이었군!
useInfiniteQuery
TanStack Query에서 제공하는 무한스크롤 및 페이지네이션 구현용 훅
데이터를 페이지 단위로 가져오고 효율적으로 캐싱하며 상태 관리 지원
특징
- data.pages: 페이지 단위 데이터를 배열에 누적 저장
- fetchNextPage: 다음 페이지 데이터 요청 함수
- 페이지네이션과 무한스크롤 모두 구현 가능
- API의 응답에 따라 nextPage 필드로 다음 페이지 관리
응답 데이터 구조
- 필수
- data: 현재 페이지 데이터 배열
- nextPage: 다음 페이지 번호 (없으면 null 반환)
- 선택
- totalPages: 전체 페이지 수
- totalItems: 전체 데이터 수
- 예제
// 기본 API 응답 예시
{
"data": [ { "id": 1, "title": "Photo 1" }, { "id": 2, "title": "Photo 2" } ],
"nextPage": 2
}
// 다음 페이지가 없을 경우
{
"data": [ { "id": 21, "title": "Photo 21" } ],
"nextPage": null
}
사용법
- 기본 페이지네이션
import { useInfiniteQuery } from "@tanstack/react-query";
const fetchPhotos = async ({ pageParam = 1 }) => {
const response = await fetch(`https://api.example.com/photos?page=${pageParam}`);
const result = await response.json();
return { data: result.data, nextPage: result.nextPage };
};
const Pagination = () => {
const { data, fetchNextPage, hasNextPage, isLoading } = useInfiniteQuery({
queryKey: ["photos"],
queryFn: fetchPhotos,
getNextPageParam: (lastPage) => lastPage.nextPage,
});
if (isLoading) return <div>Loading...</div>;
return (
<div>
{data.pages.map((page) => (
<div key={page.id}>
{page.data.map((photo) => <p key={photo.id}>{photo.title}</p>)}
</div>
))}
{hasNextPage && <button onClick={fetchNextPage}>Load More</button>}
</div>
);
};
IntersectionObserver
요소가 화면에 보이는지 비동기로 감지하여 효율적으로 스크롤 상태를 관리하는 API!
요소 감지 시, 데이터를 추가 요청하거나 로드를 실행 가능
사용법
import { useRef, useEffect } from "react";
const InfiniteScrollExample = ({ fetchMoreData }) => {
const observerRef = useRef();
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) fetchMoreData();
},
{ threshold: 1.0 }
);
if (observerRef.current) observer.observe(observerRef.current);
return () => observer.disconnect();
}, [fetchMoreData]);
return <div ref={observerRef} style={{ height: "20px", background: "gray" }} />;
};
useInfiniteQuery + IntersectionObserver
페이지네이션과 무한스크롤 모두 해결 가능!
무한스크롤로 대용량 데이터를 처리하며 성능까지 챙길 수 있ㄷr... 오...오진다아..
import { useInfiniteQuery } from "@tanstack/react-query";
import { useRef, useEffect } from "react";
const fetchPhotos = async ({ pageParam = 1 }) => {
const response = await fetch(`https://api.example.com/photos?page=${pageParam}`);
const result = await response.json();
return { data: result.data, nextPage: result.nextPage };
};
const InfiniteScroll = () => {
const { data, fetchNextPage, hasNextPage, isLoading } = useInfiniteQuery({
queryKey: ["photos"],
queryFn: fetchPhotos,
getNextPageParam: (lastPage) => lastPage.nextPage,
});
const observerRef = useRef();
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting && hasNextPage) fetchNextPage();
},
{ threshold: 1.0 }
);
if (observerRef.current) observer.observe(observerRef.current);
return () => observer.disconnect();
}, [fetchNextPage, hasNextPage]);
if (isLoading) return <div>Loading...</div>;
return (
<div>
{data.pages.map((page) => (
<div key={page.id}>
{page.data.map((photo) => <p key={photo.id}>{photo.title}</p>)}
</div>
))}
<div ref={observerRef} style={{ height: "20px", background: "lightgray" }}>Scroll down</div>
</div>
);
};
마무리 - 오늘은 노래를 준비했습니다.. (ft. 건달)
뼈를깎는 고통을 통해 오늘 tanstackquery를 성공적으로 구현했다!
그리고 개 펑펑 울었다.. 못하는 내 자신이 한심해서 어헝헝...
맘속으로 개발자 접을까 오지게 생각하고 있었는데
지금 잘 하고 있는거라고 마음써주신 다른분들께 너무 죄송스럽고.. 감사하달까
오늘 건달이 추천해준 노래들으면서 자러가야겄다.
민나 굳바2.
728x90
반응형
'React TIL' 카테고리의 다른 글
[React] Day_54 팀 프로젝트 작업 관련 트러블슈팅 (2) (0) | 2024.12.04 |
---|---|
[React] Day_53 팀 프로젝트 작업 관련 트러블슈팅 (1) (0) | 2024.12.03 |
[React] Day_51 개인 프로젝트 후기 (2) | 2024.11.29 |
[React] Day_50 데일리 정리 (2) | 2024.11.28 |
[React] Day_49 개인 프로젝트 중간점검 (1) | 2024.11.27 |