728x90
최근 React로 프로젝트를 진행하면서 페이지네이션을 구현해야 하는 상황이 있었다.
백엔드에서 모든 데이터를 한 번에 받아와서 프론트엔드에서 페이지네이션을 처리하는 방식을 선택했다. (이유는 나중에!!!)
현 과정에서 페이지네이션의 개념과 구현 방법에 대해 깊이 이해할 수 있었던 경험을 공유하고자 한다!!!!!!
페이지네이션이란?
페이지네이션은 데이터를 여러 페이지로 나누어 표시하는 UI 패턴이다.
페이지네이션의 주요 목적이 뭘까?
- 한 페이지에 모든 데이터를 표시하는 대신, 적절한 양의 데이터만 보여줌으로써 사용자가 정보를 쉽게 찾고 탐색할 수 있게 한다.
- 화면에 렌더링되는 데이터의 양을 제한함으로써 브라우저의 렌더링 부하를 줄일 수 있다.
그럼 페이지네이션 구현 방법에 대해 알아보자.
페이지네이션 구현 방법
기본 구조 설계
페이지네이션 구현을 위해서는 다음과 같은 상태값들이 필요하다:
const [currentPage, setCurrentPage] = useState(1);
const [itemsPerPage, setItemsPerPage] = useState(10);
const [totalItems, setTotalItems] = useState(0);
여기서 각 상태값의 의미는 다음과 같다:
- currentPage: 현재 페이지 번호
- itemsPerPage: 한 페이지당 표시할 아이템 수
- totalItems: 전체 아이템 수
페이지 계산 로직
페이지네이션의 핵심은 현재 페이지에 표시될 데이터를 계산하는 로직이다.
다음은 기본적인 계산 방식이다:
const indexOfLastItem = currentPage * itemsPerPage;
const indexOfFirstItem = indexOfLastItem - itemsPerPage;
const currentItems = items.slice(indexOfFirstItem, indexOfLastItem);
이 코드는 전체 데이터 배열에서 현재 페이지에 해당하는 부분만을 잘라내는 역할을 한다.
indexOfLastItem은 현재 페이지의 마지막 아이템 인덱스를, indexOfFirstItem은 첫 번째 아이템 인덱스를 계산한다.
UI 컴포넌트 구현
페이지네이션 UI는 일반적으로 페이지 번호들과 이전/다음 페이지 버튼으로 구성된다.
특히 중요한 것은 총 페이지 수가 많을 때의 처리 방식이다.
const renderPageButtons = () => {
const pageButtons = [];
const DOTS = '...';
const SIBLINGS_COUNT = 1;
// 첫 페이지와 마지막 페이지 버튼
pageButtons.push(
<PageButton onClick={() => handlePageChange(1)} disabled={currentPage === 1}>
{'<<'}
</PageButton>
);
// 페이지 번호 버튼들
if (totalPages <= 7) {
// 전체 페이지가 7개 이하면 모든 페이지 표시
for (let i = 1; i <= totalPages; i++) {
pageButtons.push(
<PageButton key={i} onClick={() => handlePageChange(i)} active={currentPage === i}>
{i}
</PageButton>
);
}
} else {
// 전체 페이지가 7개 초과면 일부만 표시하고 ... 으로 생략
const leftSiblingIndex = Math.max(currentPage - SIBLINGS_COUNT, 1);
const rightSiblingIndex = Math.min(currentPage + SIBLINGS_COUNT, totalPages);
const shouldShowLeftDots = leftSiblingIndex > 2;
const shouldShowRightDots = rightSiblingIndex < totalPages - 1;
if (!shouldShowLeftDots && shouldShowRightDots) {
// 왼쪽 dots 없음
for (let i = 1; i <= 4; i++) {
pageButtons.push(
<PageButton key={i} onClick={() => handlePageChange(i)} active={currentPage === i}>
{i}
</PageButton>
);
}
pageButtons.push(<PageButton key="dots" disabled>{DOTS}</PageButton>);
}
// ... 나머지 조건들의 구현
}
return pageButtons;
};
이 코드에서는 다음과 같은 중요한 개념들이 적용되었다:
- SIBLINGS_COUNT: 현재 페이지 양옆에 표시할 페이지 번호의 개수
- DOTS: 생략된 페이지를 표시하는 구분자
- shouldShowLeftDots/shouldShowRightDots: 생략 표시를 할지 결정하는 조건
페이지 버튼 렌더링 로직은 다음과 같은 규칙을 따른다:
- 전체 페이지가 7개 이하면 모든 페이지 번호를 표시
- 전체 페이지가 7개 초과면 현재 페이지 주변의 일부 페이지만 표시하고 나머지는 ... 으로 생략
- 항상 첫 페이지와 마지막 페이지는 표시
- 현재 페이지의 좌우로 SIBLINGS_COUNT만큼의 페이지를 표시
무작정 목록 페이지에 나오는 목록 아이템들을 나란히 다 표시하는 것 보단 페이지네이션을 쓰는 것이 UX에 엄청난 도움이 되지 않을까??
728x90
'React' 카테고리의 다른 글
[React] 웹 페이지 프린트 기능 구현하기 🖨️ (0) | 2025.02.09 |
---|---|
[React] useRef란 무엇일까? 🪝 (0) | 2025.02.08 |
[React] 이벤트 핸들링 개념정리 (1) | 2025.02.06 |
[React] Props 개념 완벽 가이드 ✔︎ (0) | 2025.02.05 |
[React] Recoil 새로고침 시 데이터 유지가 안된다?!! (1) | 2025.02.04 |