UX를 고려한 페이지네이션 설계 및 구현
UX 관점에서 본 좋은 페이지네이션 설계
웹사이트에서 페이지네이션(pagination)은 데이터를 여러 페이지로 나누어 사용자에게 제공하는 중요한 UI 요소입니다. 특히 많은 데이터를 효율적으로 탐색할 수 있도록 돕는 UX 설계가 필요합니다. 좋은 페이지네이션은 다음과 같은 특징을 가집니다.
1.1 현재 위치를 명확하게 보여주기
사용자는 현재 페이지가 몇 번째인지 한눈에 파악할 수 있어야 합니다.
현재 페이지 강조: 현재 페이지 버튼을 시각적으로 구분(예: 색상 변경)
페이지 그룹 표시: 현재 페이지가 속한 블록을 보여주어 사용자가 전체적인 맥락을 이해하도록 함
1.2 빠른 이동 경로 제공
사용자가 특정 페이지로 빠르게 이동할 수 있어야 합니다.
처음, 마지막 페이지 이동 버튼
일정 블록 단위(예: 5~6개)로 점프할 수 있는 기능
너무 많은 페이지가 한꺼번에 보이지 않도록, 적절한 개수만 표시
1.3 직관적인 인터랙션 요소 제공
비활성화된 버튼(예: 첫 페이지에서 '이전' 버튼)은 클릭할 수 없도록 설정
마우스를 올렸을 때 피드백(hover 효과) 제공
1.4 반응형 디자인 고려
모바일에서도 보기 편하도록 크기와 간격 조절
결과물
어떻게 구현했는지 설명하기에 앞서 결과물 먼저 보여드리겠습니다.

커스텀 페이지네이션 훅
위의 UX 원칙을 바탕으로 재사용 가능한 커스텀 훅을 만들었습니다.
1 usePagination의 역할
usePagination의 역할이 훅은 다음과 같은 기능을 담당합니다.
현재 페이지와 최대/최소 페이지 관리
한 번에 보여줄 페이지 개수(블록 단위) 관리
이전/다음 블록으로 이동 기능 제공
특정 페이지로 이동 기능 제공
2 usePagination 코드 및 상세 설명
usePagination 코드 및 상세 설명타입 및 반환값 정의
Page타입은number또는'nextBlock' | 'prevBlock'중 하나숫자는 실제 페이지 번호를 나타냄
'nextBlock'과'prevBlock'은 이전/다음 페이지 블록을 의미
PaginationHookReturn 인터페이스 정의
PaginationHookReturn 인터페이스 정의currentPage: 현재 선택된 페이지 번호visiblePages: 현재 화면에 보이는 페이지 목록 (예:[1, 2, 3, 'nextBlock', 10])maxPage: 최소 페이지 번호handleClickPage(page): 특정 페이지를 클릭했을 때 실행handleClickPrevPage(): 이전 페이지로 이동handleClickNextPage(): 다음 페이지로 이동handleClickPrevPages(): 이전 블록으로 이동handleClickNextPages(): 다음 블록으로 이동setMaxPage(newMaxPage):maxPage를 업데이트setMinPage(newMinPage):minPage를 업데이트하는
훅의 기본 구조 및 블록 크기 설정
initialMinPage와initialMaxPage를 받아 페이지 범위를 설정blockSize는 한 번에 보이는 페이지 개수(기본값 7)로, 이전/다음페이지 UI를 제외한 블록 개수를 의미END_BLOCK_SIZE = blockSize - 1: 양 끝 페이지에 위치할 때 가용 페이지 개수MIDDLE_BLOCK_SIZE = blockSize - 4: 중간 블록에서의 가용 페이지 개수
상태 선언
maxPage: 최대 페이지minPage: 최소 페이지currentPage: 현재 페이지 (기본적으로 minPage에서 시작)visiblePages: 현재 보이는 페이지 목록 (useEffect에서 업데이트됨)
페이지 목록 업데이트 로직
currentPage,maxPage가 변경될 때 실행됨현재 페이지가 최소/최대 페이지 범위를 벗어나면 아무 작업도 하지 않음
getBlockPages()를 호출하여visiblePages를 업데이트함
페이지 블록을 계산하는 함수들
전체 페이지 개수가
blockSize이하이면getAllPages()를 호출현재 페이지가
minPage근처면getFirstBlock()호출현재 페이지가
maxPage근처면getLastBlock()호출그 외의 경우는
getMiddleBlock()호출
getAllPages(): 모든 페이지 반환
getAllPages(): 모든 페이지 반환[1, 2, 3, 4, 5, 6]같은 전체 페이지 목록을 반환
getFirstBlock(): 처음 페이지 블록 생성
getFirstBlock(): 처음 페이지 블록 생성[1, 2, 3, 4, 5, ..., 51]형태로 반환
getLastBlock(): 마지막 페이지 블록 생성
getLastBlock(): 마지막 페이지 블록 생성[1, ..., 47, 48, 49, 50, 51]형태로 반환
getMiddleBlock(): 중간 페이지 블록 생성
getMiddleBlock(): 중간 페이지 블록 생성[1, ..., 9, 10, 11, ..., 51]형태로 반환
이벤트 핸들러 함수들
특정 페이지 선택, 이전/다음 페이지, 이전/다음 블록 이동 기능을 담당
페이지네이션 컴포넌트
페이지네이션 버튼
isDisAbled이true면 버튼을 클릭할 수 없도록disabled속성을 추가className을 동적으로 설정 (cn함수 활용)isActive가true이면 현재 선택된 버튼임을 나타내는 스타일 적용isDisAbled가true이면 버튼을 비활성화 해야 하므로 비활성화 버튼의 스타일 적용
페이지네이션 UI
paginationTools를usePagination훅에서 받아와 페이지네이션 상태를 제어
기본값을 설정하여 유연한 커스터마이징이 가능하도록 구현
paginationTools에서 페이지 이동과 관련된 함수 및 상태를 구조 분해 할당하여 사용
이전 페이지 버튼
현재 페이지가
minPage이면 비활성화<아이콘을 클릭하면handleClickPrevPage()실행
페이지 목록 버튼
이전 블록 이동 버튼 (
...)을 나타냄"prevBlock"값이 있으면handleClickPrevPages()실행
다음 블록 이동 버튼 (
...)을 나타냄"nextBlock"값이 있으면handleClickNextPages()실행
각 페이지 버튼 (숫자 버튼)을 나타냄
현재 페이지(
currentPage)와 동일하면 활성화(isActive=true)클릭 시 특정 페이지로 이동하는
handleClickPage(page)호출
다음 페이지 버튼
현재 페이지가
maxPage이면 비활성화>아이콘을 클릭하면handleClickNextPage()실행
느낀점
이번 페이지네이션 구현을 통해 UX 관점에서의 중요성을 다시 한번 깨닫게 되었습니다. 단순히 기능적인 요소가 아니라, 사용자 경험을 극대화할 수 있는 설계를 고민하는 과정이 매우 흥미로웠습니다. 앞으로도 더욱 직관적이고 효율적인 UI를 고민하며 개선해 나가고 싶습니다.
Last updated