[TIL 0331] 무한스크롤

zitto·2023년 4월 2일
0

TIL

목록 보기
23/77
post-thumbnail

▼ 설치
react infinite scroller
react infinite scroll component
yarn add react-infinite-scroller
타입스크립트 오류시 yarn add -dev @types/react-infinite-scroller

✅ 무한스크롤 방식

: 페이지를 아래로 스크롤 하다가 종단점에 도달하면
새로운 데이터가 계속해서 추가되는 페이지 처리 방법


[실습 section16]

  • import해오기 / grapql요청 및 스타일 지정하기
import { useQuery, gql } from "@apollo/client";
import type {
  IQuery,
  IQueryFetchBoardsArgs,
} from "../../src/commons/types/generated/types";
import InfiniteScroll from "react-infinite-scroller";
import styled from "@emotion/styled";
const FETCH_BOARDS = gql`
  query fetchBoards($page: Int) {
    fetchBoards(page: $page) {
      _id
      writer
      title
      contents
    }
  }
`;
const Wrapper = styled.div`
  height: 500px;
  overflow: auto;
`;
  • 게시글 데이터와 fetchmore기능을 위한 선언
export default function StaticRoutingMovedPage(): JSX.Element {
  //어떤 페이지를 더 패치할 것인지!!
  const { data, fetchMore } = useQuery<
    Pick<IQuery, "fetchBoards">,
    IQueryFetchBoardsArgs
(FETCH_BOARDS);
  • 스크롤이 페이지 하단 끝에 닿을 때 실행할 기능을 onLoarMore함수로 만들기
const onLoadMore = (): void => {
    if (data === undefined) return;
    void fetchMore({
      //page : 패치모어로 패치할 페이지 = 다음페이지(+1)
      variables: { page: Math.ceil((data?.fetchBoards.length ?? 10) / 10) + 1 },
      updateQuery: (prev, { fetchMoreResult }) => {
        if (fetchMoreResult.fetchBoards === undefined) {
          return {
            fetchBoards: [...prev.fetchBoards],
          };
        }
        return {
          fetchBoards: [...prev.fetchBoards, ...fetchMoreResult.fetchBoards],
        };
      },
    });
  };

->onLoadMore 함수 최상위에 data가 없으면 실행하지 않도록 if문을 추가한다.
-> useQuery에서 제공하는 fetchMore 함수를 함께 사용해
다음 page에 해당하는 데이터를 불러와 기존 데이터 뒤에 이어지도록 붙여 줄 수 있다.
-> 조건문으로 마지막으로 받아올 추가데이터가 없다면(리패치할 것이 없다면) 기존댓글,
추가데이터 있으면 기존(이전)댓글 + 추가댓글을 리턴!
-> 무한스크롤 적용하고 싶은 영역을 InfiniteScroll로 감싼다.


  • table형태로 완성한 결과
import { useQuery, gql } from "@apollo/client";
import type {
  IQuery,
  IQueryFetchBoardsArgs,
} from "../../src/commons/types/generated/types";
import InfiniteScroll from "react-infinite-scroller";
import styled from "@emotion/styled";
const FETCH_BOARDS = gql`
  query fetchBoards($page: Int) {
    fetchBoards(page: $page) {
      _id
      writer
      title
      contents
    }
  }
`;
const Wrapper = styled.div`
  height: 500px;
  overflow: auto;
`;
export default function StaticRoutingMovedPage(): JSX.Element {
  const { data, fetchMore } = useQuery<
    Pick<IQuery, "fetchBoards">,
    IQueryFetchBoardsArgs
(FETCH_BOARDS);
  const onLoadMore = (): void => {
    if (data === undefined) return;
    void fetchMore({
      variables: { page: Math.ceil((data?.fetchBoards.length ?? 10) / 10) + 1 },
      updateQuery: (prev, { fetchMoreResult }) => {
        if (fetchMoreResult.fetchBoards === undefined) {
          return {
            fetchBoards: [...prev.fetchBoards],
          };
        }
        return {
          fetchBoards: [...prev.fetchBoards, ...fetchMoreResult.fetchBoards],
        };
      },
    });
  };
  return (
    <Wrapper>
      <InfiniteScroll
        pageStart={0}
        loadMore={onLoadMore}
        hasMore={true}
        useWindow={false}

        <table className="table">
          <th>제목</th>
          <th>이름</th>
          <th>내용</th>
          {data?.fetchBoards.map((el) => (
            <tr key={el._id}>
              <td style={{ margin: "10px", border: "solid" }}>{el.title}</td>
              <td style={{ margin: "10px", border: "solid" }}>{el.writer}</td>
              <td style={{ margin: "10px", border: "solid" }}>{el.contents}</td>
            </tr>
          )) ?? <div></div>}
        </table>
      </InfiniteScroll>
    </Wrapper>
  );
}

profile
JUST DO WHATEVER

0개의 댓글