개요

영화 리뷰 사이트 프로젝트(MOVIELOG) 진행 중, 유저들이 작성한 리뷰들을 보여주는 방법을 고민하는 과정에서 팀원들과 상의 후 페이지네이션을 이용하기로 결정했다.

무한스크롤과 페이지네이션 중 고민했지만, 리뷰에 있어서는 모든 리뷰를 열람하고 싶은 유저도 있을 것이고 아닌 유저도 있을 것이기 때문에 무한스크롤보다는 유저에게 선택권을 주어 다음 리뷰목록을 유저가 직접 클릭해서 볼 수 있는 페이지네이션이 이 상황에선 더 적절하다고 생각했다.

전반적 로직(의사코드)

  1. 각 페이지에는 최대 5개의 리뷰가 보여야한다.
  2. 해당 페이지의 최대 리뷰 수인 5개가 넘지 않으면 page number는 해당 페이지까지만 보여야 한다. ex) 유저가 2페이지에 있는 상황에서 리뷰가 3개있으면 page number는 1과 2만 존재해야함.
  3. 영화 포스터에 라우터를 “/movies/movieId” 와 같이 설정했으므로, 그냥 포스터를 클릭했을땐 디폴트 값인 1이 page number로 들어와야한다.
  4. 각 page number를 클릭시 라우터가 해당 페이지의 endpoint에 걸려 해당 페이지의 리뷰를 보여줘야 한다. ex) /movies/movieId?page=2

구현

  1. 우선, 백엔드 팀원과 상의 후 백엔드 쪽에서 각 페이지 별로 다른 리뷰들을 보내주기로 결정했다. 따라서 endpoint는 /movies/movieId?page=pageNumber 와 같이 정했다. 여기서 고려해야 했던 점은, 메인페이지에서 각 영화 포스터를 클릭 시 그냥 /movies/movieId 로 라우터를 설정했는데, 이렇게 되면 페이지 수가 디폴트값으로 page=1이 되지 않으므로 리액트 라우터 돔의 useSearchParams()을 이용하여,
// DetailsPage.tsx

const [searchParams] = useSearchParams();
const page = searchParams.get('page');
const pageNumber = Number(page || 1);

위와 같이 설정해주었다. 이 코드를 통해서 각 페이지마다 페이지 번호(pageNumber)를 얻을 수 있게되었다.

  1. 위에서 설정한 것 처럼, 그냥 메인페이지에서 영화 상세페이지로 이동하는 경우 외에도 유저가 리뷰페이지 번호를 클릭할 때 마다 해당 페이지의 endpoint로 이동하게 하기위해 각 번호마다 라우터를 걸어주어야 한다. 이를 위해서
// DetailsPage.tsx

<div className="flex justify-center text-3xl">
	<Pagination totalReviews={totalReviews} movieId={movieId} pageNumber={pageNumber} />
</div>

위와 같이 Pagination이라는 컴포넌트를 따로 만들어 페이지 번호를 화면에 렌더링 해주었다. 전달한 props는 현재 유저가 위치한 pageNumber, 현재 위치한 영화를 명시하기 위한 movieId, 페이지네이션 로직구현을 위한 totalReviews 이다.