React Pagination, Infinite Scroll

lynn·2022년 5월 28일
0

Front-End

목록 보기
12/24

Pagination

페이지 번호를 클릭해서 이동하는 방식의 페이지 처리 방법
주로 게시판 페이지에서 많이 사용됨

  1. page 인자를 사용해서 게시글 목록 불러오기

게시글을 보여주는 api(ex: fetchBoard)를 이용해서 게시글 목록을 불러온다.
graph ql의 경우 gql을 이용해서 쿼리문을 선언하고, useQuery에 담는다.

const FETCH_BOARDS = gql`
  query fetchBoards($page: Int) {
    fetchBoards(page: $page) {
      _id
      writer
      title
    }
  }
`;
  1. 페이지 클릭 시 게시글 목록 데이터 다시 불러오기 (refetch)
const { data, refetch } = useQuery(FETCH_BOARDS);

data 변수 외에 refetch가 또 있다. 기존 fetch api를 그대로 이용해서 다시 보여주는 개념이다.
선언한 다음에는 보통 onClick 이벤트 핸들러 함수에서 사용한다.

const onClickPage = (event) => {
    refetch({ page: Number(event.target.id) });
  };

fetchBoard에 필요한 인자가 page이기 때문에 {}안에 page를 넣는데 event.target.id가 문자열이라 Number로 형 변환을 했다.

공식문서 refetching 사용법
https://www.apollographql.com/docs/react/data/queries/#refetching

  1. map 메소드로 페이지 번호 브라우저에 보여주기

한번에 열 개의 페이지 번호를 보여준다고 하면 페이지 번호 컴포넌트를 10개 만드는 것보다 map으로 만들어서 반복하는 것이 효율적이다.

{new Array(10).fill(1).map((_, index) => (
  <span
    onClick={onClickPage}
    id={String(index + startPage)}
    key={index + startPage}
  >
    {` ${index + startPage} `}
  </span>
))}
  1. 페이지네이션 이전, 다음으로 이동+refetch 구현

  2. 이전 페이지 미만, 마지막 페이지 이상으로 넘어가지 않도록 설정

// 이전 페이지 클릭 시 실행할 함수
  const onClickPrevPage = () => {
	// startPage가 1이면 하단 스크립트를 실행하지 않고 종료한다.
  if (startPage === 1) return;
  setStartPage((prev) => prev - 10);
  refetch({ page: startPage - 10 });
};

// 다음 페이지 클릭 시 실행할 함수
const onClickNextPage = () => {
	// startPage + 10가 lastPage보다 클 경우 하단 스크립트를 실행하지 않고 종료한다.
  if (startPage + 10 > lastPage) return;
  setStartPage((prev) => prev + 10);
  refetch({ page: startPage + 10 });
};
	

Infinite Scroll(무한 스크롤)

직접 구현하면 더 좋겠지만, 라이브러리를 이용했다.

  1. react-infinite-scroller를 이용해서 import
import InfiniteScroll from "react-infinite-scroller";
  1. fetchMore 이용
const { data, fetchMore } = useQuery(FETCH_BOARDS);

  const loadFunc = () => {
    if (!data) return;
    fetchMore({
      variables: { page: Math.ceil(data.fetchBoards.length / 10) + 1 },
      updateQuery: (prev, { fetchMoreResult }) => {
        if (!fetchMoreResult.fetchBoards)
          return { fetchBoards: [...prev.fetchBoards] };

        return {
          fetchBoards: [...prev.fetchBoards, ...fetchMoreResult?.fetchBoards],
        };
      },
    });
  };
  1. 무한 스크롤 적용
<InfiniteScroll
        pageStart={0}
        loadMore={loadFunc}
        hasMore={true || false}
        loader={
          <div className="loader" key={0}>
            Loading ...
          </div>
        }
        useWindow={false}
      >

DOM 스크롤: 정해진 구역에서 스크롤
Window 스크롤: 브라우저 전체 화면에서 스크롤

profile
개발 공부한 걸 올립니다

0개의 댓글