eokeuroding 님의 블로그

데이터 처리 기법 - 페이지네이션 본문

카테고리 없음

데이터 처리 기법 - 페이지네이션

eokeuroding 2025. 5. 11. 18:36

Git : DynamicDataHandling/Pagination at main · dasom-jo/DynamicDataHandling

1.페이지네이션(Pagination)

웹에서 효율적인 데이터 표시방법

많은 양의 데이터를 한 번에 사용자에게 보여주는 것은 성능이나 사용자 경험 측면에서 비효율적입니다. 그래서 대부분의 웹사이트는 데이터를 나누어 순차적으로 제공하는 방식을 사용하며, 이를 페이지네이션이라고 합니다. \

 

2.왜 페이지네이션이 필요한가요

  • 성능 향상 : 수천개의 데이터가 한번에 렌더링 되면 브라우저가 느려집니다.
  • 사용자 경험 개선 : 사용자가 정보를 찾기 쉽게 그룹화 할수있습니다.

3.페이지네이션 vs. 무한 스크롤 vs. 가상 스크롤

방식 설명 장점 단점
페이지네이션 일정 개수만큼 잘라서 페이지별로 보여줌 직관적이고 컨트롤이 쉬움 사용자 클릭이 필요
무한스크롤 사용자가 스크롤할때마다 데이터를 계속 불러옴 자연스럽고 몰입도 높은 UX 페이지 이동이 어려움
가상 스크롤 실제 렌더링은 화면에 보이는 부분만 함 퍼포먼스 최적화에 강함 구현 난이도 높음

 

4.페이지네이션의 구성 요소

  • 현재 페이지(current page) : 사용자가 현재 보고있는 페이지 번호
  • 총 데이터 수 (total items) : 전체 데이터가 몇개인지
  • 페이지 당 항목 수 (items per page) : 한페이지에 표시할 데이터의 개수
  • 총 페이지 수 (total pages) : Math.ceil (총 데이터 수 / 페이지당 항목 수)
  • 페이지 이동 컨드롤 : 이전, 다음 버튼, 숫자 페이지 버튼, 첫 페이지/ 마지막 페이지 이동

5. 페이지네이션 구현 시 고려할 점

  • 페이지 변경 시 스크롤 위치 초기화 여부
  • URL에 페이지 정보를 반영할지 여부 (/page/3)
  • 현재 페이지 강조 스타일링
  • 데이터 없는 페이지로 접근 방지 처리
  • 반응형 환경에서의 UX 최적화

6.페이지네이션 방식 종류

  • 서버 사이드 페이지네이션  : 백엔드가 필요한 데이터만 전송, 대규모 데이터에 적합, 쿼리스트링(?page=2)기반요청
  • 클라이언트 사이드 페이지네이션 : 프론트엔드에서 모든 데이터를 받고 페이지별로 나누어 표시, 데이터 양이 적을 때 적합, 빠른 페이지 이동 가능하지만 초기 로딩이 오래걸릴수있음.

7.페이지네이션 구현( 라이브러리 ❌ )

// useGetTopRateMovies.js
import { useQuery } from "@tanstack/react-query";

const FetchTopRatedMovies = async (page) => {
  const res = await fetch(
    `https://api.themoviedb.org/3/movie/top_rated?page=${page}`,
    {
      headers: {
        Authorization: `Bearer ${process.env.REACT_APP_API_KEY}`,
        accept: "application/json",
      },
    }
  );
  if (!res.ok) throw new Error("데이터 요청 실패");
  return res.json();
};

const useGetTopRateMovies = (page) => {
  return useQuery({
    queryKey: ["top-rated-movie", page],
    queryFn: () => FetchTopRatedMovies(page),
    keepPreviousData: true,
  });
};

export default useGetTopRateMovies;
// MovieList.jsx
const [currentPage, setCurrentPage] = useState(1);
const { data, isLoading } = useGetTopRateMovies(currentPage);

<button onClick={() => setCurrentPage((p) => p - 1)} disabled={currentPage === 1}>
  ◀ Prev
</button>

<span>{currentPage} / {data?.total_pages}</span>

<button onClick={() => setCurrentPage((p) => p + 1)} disabled={currentPage === data?.total_pages}>
  Next ▶
</button>