메시지 내역을 서버 페이지네이션으로 전환한 과정
전체 메시지 내역을 한 번에 조회하던 구조를 페이지 단위 서버 조회로 바꾸고 검색 시 페이지 상태를 일관되게 관리한 과정을 정리합니다.
메시지 발송 내역 화면은 날짜 범위의 전체 데이터를 받아 브라우저에서 검색하고 페이지를 나누고 있었다. 화면에는 10건만 보여도 네트워크와 메모리는 전체 목록의 비용을 먼저 지불하는 구조였다.
페이지 UI만으로는 조회량이 줄지 않았다
기존 API는 지점과 시작일·종료일만 전달했다.
아래 코드 예시는 설명을 위해 식별자와 운영 설정값을 일반화했습니다.
listMessages(organizationId, fromDate, toDate)
화면의 Pagination 컴포넌트는 이미 받은 배열의 길이를 기준으로 페이지를 만들었다. 데이터가 늘면 응답 크기와 초기 처리량도 함께 증가한다. 이 문제는 React 렌더링 라이브러리를 바꾸는 것으로 해결되지 않는다. 서버가 반환하는 데이터 범위 자체를 줄여야 했다.
현재 페이지를 API 계약에 포함했다
팀 변경에서는 조회 함수에 pageNum을 추가하고 쿼리 파라미터로 전달했다.
export const listMessages = (organizationId, fromDate, toDate, page) =>
client.get("/api/messages", { params: { organizationId, fromDate, toDate, page } });
화면은 currentPage가 바뀔 때 API를 다시 호출하고, 각 응답 행에 포함된 전체 건수 count를 별도 상태로 저장했다. 목록 길이가 아니라 서버의 전체 건수를 페이지네이션 컴포넌트에 전달한 것이 중요한 차이다.
useEffect(() => { loadCurrentPage(); }, [page]);
setRows(result.items);
setTotalCount(result.total);
<Pager page={page} total={result.total} onChange={setPage} />
검색 버튼을 누르면 페이지를 1로 되돌렸다. 이전 검색에서 5페이지를 보고 있던 사용자가 결과가 한 페이지뿐인 조건으로 검색할 때 빈 화면에 머무는 문제를 막기 위해서다.
페이지와 전체 건수를 같은 조회 계약으로 관리했다
변경된 목록 조회 흐름은 다음과 같다.
- 요청에 현재 페이지 번호가 포함됐다.
- 페이지 변경 시 해당 범위를 다시 조회했다.
- 전체 건수와 현재 페이지 목록을 분리해 관리했다.
- 검색 조건이 바뀌면 첫 페이지로 초기화했다.
전체 조회를 페이지 단위 조회로 바꿔 데이터가 늘어도 한 번에 전송하는 목록의 범위를 제한했다. API 계약과 화면 상태를 함께 바꾼 팀 작업이었다.
서버 페이지네이션은 단순한 UI 기능이 아니다. 현재 페이지 목록, 전체 건수, 검색 조건, 페이지 초기화 규칙이 하나의 계약으로 맞물려야 데이터가 늘어도 예측 가능한 목록이 된다.