React infinit scroll 적용시키기

sagong·2020년 1월 1일
3

react

목록 보기
1/4

오늘은 리스트를 받아오고 스크롤을 내릴때 로딩 스크롤이 나올수 있는 기능을 넣어보았다.

가장먼저 생각 한것, 쿼리문을 어떻게 수정해야할까.
최소한으로 필요한 사항은 한번에 몇개의 데이터를 가져올것인지.
그리고 게시판으로 생각하면 내가 어떤 페이지의 정보를 가져왔는지 이다.

구글링을 해 보았을때, 기본적 REST API 서버에서 가져올때
https://reactgo.com/react-infinite-scroll/
이와 같은 방법을 쓸수 있을것 같다.
이 방법은 기본적으로 react-infinite-scroll-component 모듈을 사용하였다.
데이터를 받아오게 되면 기존 state에 있는 정보에 새로운 정보를 추가하는 방법으로 되어 있었다.

이 모듈을 사용하는 자세한 방법은
https://github.com/ankeetmaini/react-infinite-scroll-component#readme
여기에 있다. live example도 있고 설명이 편한듯 해 보인다. 이 모듈을 사용하기로 하였다.

저는 Apollo 와 Graphql를 활용하고 있기 때문에 이에 맞는 방법을 찾아보았다.

Apollo

  1. Apollo는 Client, Server 라이브러리, 캐싱 및 쿼리 분석도구를 제공한다.
  2. REST API와 Redux를 대체하는 GraphQL과 Apollo.
  3. graphql을 기반으로 한 상태관리 플랫폼이다. 클라이언트에서 graphql을 사용하여 데이터를 가져오는 UI를 만들 때 사용하기 좋다.
  4. 특히 React하고 결합이 좋다. => 컴포넌트 자체에 Query를 녹여서 구현하기가 쉬워진다.

yarn install apollo-boost react-apollo graphql
apollo-boost : Apollo Client를 설정하는데 필요한 것이 들어있는 패키지
react-apollo : React를 위한 apollo
graphql : GraphQL 쿼리를 사용할 수 있다.

https://sysgears.com/articles/how-to-implement-infinite-scroll-with-graphql-and-react/
이 블로그에 어느정도 잘 설명이 되어 있었다.
Apollo 에서 제공하는 fetchMore()를 활용하여 기능을 구현하기로 하였다.

자세한 방법은
https://www.apollographql.com/docs/react/data/pagination/#offset-based

  1. 서버단에서 Query 문을 수정 추가 함.

seeFeeds.graphql

type Query{
    seeFeeds(pageNumber: Int!, items: Int!):[Post!]!
}

seeFees.js

Query: {
        seeFeeds: async (_, args, { request, isAuthenticated }) => {
            console.log(args.pageNumber);
            isAuthenticated(request);
            const { user } = request;
            const following = await prisma
                .user({ id: user.id })
                .following()

            return prisma.posts({
                first:args.items,
                skip:args.pageNumber,
                where: {
                    user: {
                        id_in: [...following.map(user => user.id),user.id]
                    }
                },
                orderBy: "createdAt_DESC"

            })
        }
    }

items는 한번에 몇개씩 받아올지 에 대한 값, pageNumber는 요청한 page 값

  1. frontpage 수정
  const { data, loading, refetch, fetchMore } = useQuery(FEED_QUERYS, {
    variables: {
      pageNumber,
      items
    }
  });
  
    const onLoadMore = () => {

    fetchMore({
      variables: {
        pageNumber: data.seeFeeds.length,
        items
      },
      updateQuery: (prev, { fetchMoreResult }) => {
        if (!fetchMoreResult) return prev;
        return Object.assign({}, prev, {
          seeFeeds: [...prev.seeFeeds, ...fetchMoreResult.seeFeeds]
        });
      }
    })

  }

원래 data만 받아 왔지만, fetchMore()을 사용하기위해 받아 왔다.
또한 스크롤이 내려갔을때 정보를 받아 올수 있는 onLoadMore 메소드를 만들었다.
더 많은 정보를 받아오게 되면 기존의 정보에 새로운 정보가 추가된 배열이 구성된다.

yarn add react-infinite-scroll-component
yarn add react-spinners

react-infinite-scroll-component 설치, 추가적으로 loading spinner를 사용하기 위해 찾아보다가 react-spinners를 사용하기위해 추가.

{!loading &&
        data &&
        data.seeFeeds && (
          <InfiniteScroll
            dataLength={data.seeFeeds.length}
            next={onLoadMore}
            hasMore={true}
            loader={<ClipLoader
                      css={override}
                      size={35}
                      color={"#999999"}
            />}
          >
            {data.seeFeeds.map(post => (
              <Post
                key={post.id}
                id={post.id}
                location={post.location}
                caption={post.caption}
                user={post.user}
                files={post.files}
                likeCount={post.likeCount}
                isLiked={post.isLiked}
                comments={post.comments}
                createdAt={post.createdAt}
              />
            ))}
          </InfiniteScroll>
        )}
profile
안녕하세요

0개의 댓글