프론트 132 - infinite scroller

규링규링규리링·2024년 9월 30일

프론트 공부하기

목록 보기
132/135

infinite scroller

const a = ["a","b","c"]
const b = ["d","e"]

이 둘을 합치려면?

const c = [a,b]

이런식으로 넣으면 단순히 배열 a와b를 원소로 갖는 c가되버림

const c = [...a, ...b]

이런식으로 스프레드하면?

성공!

위의 기능을 사용해서 댓글 무한스크롤을 만들어 보자

이런식으로 기존의 댓글들 목록에 추가댓을을 추가해서 전체댓글을 만드는 내용을 만들어야한다

스크롤

먼저 스크롤 기능을 하는 라이브러리를 넣자
react-infinite-scroller
react-infinite-scroll-component

둘 기능이 비슷함
컴포넌트는 핸드폰으로 손가락으로 내릴때 추가기능들이 있음

여기선 인피니트 스크롤러로 해보자.

설치하고 import를 해보면 위와같은 경고문이 뜬다.

대충 설명하면
@types/react-infinite-scroller 를 설치하라고 하는 내용인데
라이브러리를 JavaScript로 만든 경우
1. JS->TS로 변경하는 방법
2. TS부분만 따로 만드는 방법
두가지 방법이 있다.
위 경우는 2번처럼 따로 만든 경우라서 현재 다운 받은것은 JS이므로 TS를 받으라는 내용이 뜨는것.
TS용 react-infinite-scroller
이것도 받아주도록 하자

npm i --save-dev @types/react-infinite-scroller
이므로
npm => yarn
i(install) => add
--save-dev => --dev
뒤는 동일하게 하면된다.

적용시키기

<InfiniteScroll pageStart={0} loadMore={onLoadMore} hasMore={true}>
  {data?.getBoards?.map(el => (
  <div key={el?.id}>
    <span style={{ margin: "15px" }}>{el?.title}</span>
    <span style={{ margin: "15px" }}>{el?.writer}</span>
  </div>
  ))}
</InfiniteScroll>

스크롤할 내용을 InfiniteScroll로 감싸고

const onLoadMore = ():void => {
  if (data === undefined) return;

  void fetchMore({
    variables:{page: Math.ceil((data?.getBoards?.length ?? 10) / 10) + 1},
                               updateQuery: (prev,{fetchMoreResult}) => {
      const prevBoards = prev.getBoards ?? [];
      const newBoards = fetchMoreResult?.getBoards ?? [];
      return {
        getBoards: [...prevBoards, ...newBoards]
      };
    }
  })
};

게시글을 추가로 불러오는 fetchMore를 만들어주면된다.

길게 나오는 모습.
만약 정해진 박스 내에서만 스크롤을 만들고 싶으면

이처럼 div로 감싸고 높이를 지정해주면 된다.

<div style={{ height: "300px", overflow: "auto" }}>
  <InfiniteScroll pageStart={0} loadMore={onLoadMore} hasMore={true} useWindow={false} >
    {data?.getBoards?.map(el => (
      <div key={el?.id}>
      <span style={{ margin: "15px" }}>{el?.title}</span>
      <span style={{ margin: "15px" }}>{el?.writer}</span>
    </div>
    ))}
  </InfiniteScroll>
</div>

0개의 댓글