1 분 소요

1. 무한 스크롤

무한 스크롤 방식은 아래로 스크롤할 때, 계속해서 페이지가 추가되어 보여주는 방식의 페이지 처리 방법이다. 무한 스크롤 라이브러리를 nmpjs.com에 검색해보면, React Inifinte Scrollerreact-infinite-scroll-component 이 두 가지가 가장 인기가 많다. (나는 전자를 사용했다!)


npmjs.com: React Inifinte Scroller npmjs.com: react-infinite-scroll-component


import { useQuery, gql } from "@apollo/client";
import styled from "@emotion/styled";
import InfiniteScroll from "react-infinite-scroller";

const FETCH_BOARDS = gql`
  query fetchBoards($page: Int) {
    fetchBoards(page: $page) {
      # variables로 받은 페이지
      _id
      writer
      title
      contents
    }
  }
`;

const MyRow = styled.div`
  display: flex;
`;

const MyColumn = styled.div`
  width: 25%;
`;

export default function MapBoardPage() {
  const { data, fetchMore } = useQuery(FETCH_BOARDS);

  const onLoadMore = () => {
    if (!data) return;
    // 데이터가 없다면 스크롤이 실행될 필요 없어! 더 많이 요청할 필요도 없어!
    // (data가 undefined일 때도 <InfiniteScroll></InfiniteScroll>은 있기 때문에)

    fetchMore({
      // 기존에 10개가 있는데 추가로 페치해줌, 리페치 아님!
      variables: { page: Math.ceil(data.fetchBoards.length / 10) + 1 },
      // 어떤 페이지를 페치할 건데? ($page 내용) : 받아온 데이터.페치보드의 객체 개수를 10으로 나눠서 올려주기(현재 몇 페이지까지 받았는지?) + 1(그 다음페이지를 추가로 요청할 것이기 때무네~)
      updateQuery: (prev, { fetchMoreResult }) => {
        // 받아온 useQuery를 수정하는 부분 (useQuery로 요청한 거, {추가로 요청한 거})

        // 만약에 추가로 요청했는데 그 페이지가 0개일 경우! 그대로 받아온다!
        if (!fetchMoreResult.fetchBoards)
          return { fetchBoards: [...prev.fetchBoards] };

        return {
          fetchBoards: [...prev.fetchBoards, ...fetchMoreResult.fetchBoards],
        };
        // 리턴: "페치보드를 업데이트 해줘!"
        // 이전에 받은 10개랑 추가로 받은 개수 보여주면 됨
        // {기존에 fetchBoards한 거를 [...기존꺼 10*n개, ...추가 10개]로 바꿔줘}
      },
    });
  };

  return (
    // <div style=>
    // useWindow={false}일 때 (내부 스크롤 사용하고 싶을 때) 700px 넘어가면 스크롤이 생긴다는 뜻
    <InfiniteScroll
      pageStart={0} //
      loadMore={onLoadMore} // 더 내렸을 때 있으면 이 함수를 실행시켜 주겠다
      hasMore={true} // 더 있는지 없는지
      // loader를 추가하면 로딩되는 동안 보여줄 내용 넣을 수 있음
      // useWindow={false} -> true면 윈도우바디에 있는 스크롤을 사용하겠다는 뜻
    >
      {data?.fetchBoards.map((el) => (
        <MyRow key={el._id}>
          <MyColumn>{el._id}</MyColumn>
          <MyColumn>{el.writer}</MyColumn>
          <MyColumn>{el.title}</MyColumn>
        </MyRow>
      )) || <></>}
      {/* 자식이 없으면 콘솔창에 에러가 뜨기 때문에 넣어준 fragment */}
    </InfiniteScroll>
    // </div>
  );
}

댓글남기기