Pagination vs Infinite Scroll

남예지·2022년 12월 22일
0

게시판에서 글을 보여주는 방법중에 글 목록을 한페이지씩 보여주는 페이지 네이션과 스크롤 하면 무한으로 스크롤이 내려가면서 목록을 보여주는 무한 스크롤방식이 있습니다.

이 두 방식을 사용하는 방법을 알아봅시다.

Pagination

페이지네이션이란 페이지번호를 클릭해서 이동하는 방식의 페이지 처리방법이다.
게시글 목록을 페이지네이션으로 설정하기
스크롤 방식도 페이지네이션이다.

이전페이지 / 다음페이지

일단 장소는 아까 게시글 페이지네이션의 앞뒤로 들어가줘야하니 span으로 만들어준다.
그리고 span 안에는 클릭 시 이전/다음 페이지로 넘어갈 수 있는 함수를 넣어주기 위해
onClick을 넣어준 뒤 함수를 만들어 바인딩해 준다.

  const onClickPrevPage = () => {
  };

  const onClickNextPage = () => {
  };
  
      <span onClick={onClickPrevPage}>이전페이지</span>
      {/* 실무에서는 el을 안쓰면 안쓴다는 의미로 _ 를 넣는다. */}
      {new Array(10).fill(1).map((_, index) => (
        <span
          key={index + 1}
          id={String(index + 1)}
          onClick={onClickPage}
          style={{ margin: "10px" }}
        >
          {index + 1}
        </span>
      ))}
      <span onClick={onClickNextPage}>다음페이지</span>

함수 안에는 눌렀을 때 10페이지 뒤/앞으로 가야하기에 useState에 startPage를 기본값 1로 저장하고 누를때마다 10페이지씩 늘어가는 값을 저장하게 해준다. 그리고 이를 refetch해줘야한다.
코드는 아래와 같다.

const [startPage, setStartPage] = useState(1);

const onClickPage = (event: MouseEvent<HTMLSpanElement>) => {
    //기다려야하면 async/await 하면 된다.
    void refetch({ page: Number(event.currentTarget.id) });
  };
  
const onClickPrevPage = () => {
    setStartPage((prev) => prev - 10);
    void refetch({ page: startPage - 10 });
  };

  const onClickNextPage = () => {
    setStartPage((prev) => prev + 10);
    void refetch({ page: startPage + 10 });
    // setStartPage(startPage + 10) 해도 동일하다
  };

그러니 아까 map으로 게시글 목록을 부를 때 + 1 했던걸 startPage로 바꿔준다.

<span onClick={onClickPrevPage}>이전페이지</span>
      {/* 실무에서는 el을 안쓰면 안쓴다는 의미로 _ 를 넣는다. */}
      {new Array(10).fill(1).map((_, index) => (
        <span
          key={index + startPage}
          id={String(index + startPage)}
          onClick={onClickPage}
          style={{ margin: "10px" }}
        >
          {index + startPage}
        </span>
      ))}
      <span onClick={onClickNextPage}>다음페이지</span>

여기서 문제는 이전 페이지를 계속 누르다보면 없는 페이지도 계속 나오는데 이를 방지해줘야한다.
startPage가 1일 때 이전페이지를 못누르게 하면 이전페이지로 계속 넘어가는 문제는 해결된다.
그런데 다음페이지로 넘어갈 때는 마지막 페이지를 알아야한다.
만약 105페이지가 마지막 페이지라고 하면 110까지만 보여주고 이후에는 다음페이지가 나오면 안된다.
startPage +10 가 lastPage보다 크면 다음페이지가 비활성화되게 한다.

const onClickPrevPage = () => {
    if (startPage === 1) return;
    setStartPage(startPage - 10);
    void refetch({ page: startPage - 10 });
  };

  const onClickNextPage = () => {
    if (startPage + 10 <= lastPage) {
      setStartPage(startPage + 10);
      void refetch({ page: startPage + 10 });
    }
  };
  
  <span onClick={onClickPrevPage}>이전페이지</span>
      {new Array(10).fill("철수").map(
        (_, index) =>
          index + startPage <= lastPage && (
            <span
              key={index + startPage}
              id={String(index + startPage)}
              onClick={onClickPage}
              style={{ margin: "10px" }}
            >
              {index + startPage}
            </span>
          )
      )}
  • refetch에 오류 문구는 void를 앞에 붙이면 해결되는데 만약 promise를 리턴한다면 void 대신 async/awite 를 하고, 기다릴 필요가 없으면 void를 한다.

Infinite Scroll

이걸 해주는 라이브러리 중 유명한게 2가지 있다.

  1. search packages
    //웹에서는 심플하다.

  2. react-infinite-scroll-component

//안에 있는 옵션은 둘 다 동일하거나 비슷하다.

2를 사용해보자.
터미널에 설치해준다.
https://www.npmjs.com/package/@storybook/react
여기를 들어가 Getting Started를 보고 설치하면 된다.

yarn add react-infinite-scroller

이때 타입스트립트를 사용하고 있으니 타입스크립트 전용으로 하나 더 설치해준다.

yarn add --dev @types/react-infinite-scroller

import 해준다.

import InfiniteScroll from 'react-infinite-scroller';

스크롤이 되면 fetchmore를 해준다.

export default function StaticRoutedPage() {
  const { data, fetchMore } = useQuery<
    Pick<IQuery, "fetchBoards">,
    IQueryFetchBoardsArgs
  >(FETCH_BOARDS);

  const onLoadMore = () => {
    fetchMore({
      variables: { page: 2 },
      updateQuery: () => {},
    });
  };
  
return (
    <InfiniteScroll pageStart={0} loadMore={onLoadMor} hasMore={true}>
      {data?.fetchBoards.map((el) => (
        <div key={el._id}>
          <span style={{ margin: "10px" }}>{el.title}</span>
          <span style={{ margin: "10px" }}>{el.contents}</span>
        </div>
      ))}
    </InfiniteScroll>
  );
}

InfiniteScroll로 감싸준 뒤 속성 pageStart={0} loadMore={onLoadMor} hasMore={true} 을 적어준다.


상황에 맞는 페이지 로드 방법을 활용하면 좋겠습니다.

profile
총총

0개의 댓글