본문 바로가기

TIL

아웃소싱 팀 프로젝트 ④ - Infinite Scroll

피드에 게시물들이 쌓이게 되었을 때 모든 게시물을 한번에 가져오는 것 보다는 사용자가 스크롤 할 때마다 새로운 게시물을 불러오는 것이 좀 더 효율적 일 것 같아 useInfiniteQuery를 이용하여 무한스크롤을 구현했다.

useQuery의 페이지와 옵저버 상태 관리를 useInfiniteQuery가 알아서 해줌으로써 관리와 유지보수가 편리하다.

 

■ 무한스크롤

☀︎ 최종코드

컴포넌트 하단에 <div ref={ref} /> 를 추가하여 div가 옵저버 역할로 다음페이지를 가져올지 여부를 판단한다!

// feedApi.js
export const getFeedPages = async ({ pageParam = 1 }) => {
  const response = await feedInstance.get(`/feed?_sort=created_time&_order=desc&_page=${pageParam}&_limit=5`);
  return response.data;
};
// Posting.jsx
const {
    data: feeds,
    hasNextPage,
    fetchNextPage,
    isFetchingNextPage
  } = useInfiniteQuery({
    queryKey: ["feeds"],
    queryFn: getFeedPages,
    getNextPageParam: (lastPage, pages) => {
      return lastPage.length === 5 ? pages.length + 1 : undefined;
    },
    select: (data) => data.pages.flat()
  });
  
const { ref } = useInView({
    // ref element가 0.5(절반)만큼 보이면 onChange 함수 실행
    threshold: 0.5,
    onChange: (inView) => {
     // 예외처리 (ref가 inView 안에 없거나, nextPage가 없거나, 다음페이지를 불러오는 중이거나)
     if (!inView || !hasNextPage || isFetchingNextPage) return;
     fetchNextPage();
    }
  });

 

 

☀︎ 버전 변경에 따른 페이지 요청 방법 변경

json-server 설치 시 가장 최신인 1.0.0-beta.2 버전이 설치되는데 버전을 0.17.4 로 낮췄었고 그에 맞게 무한스크롤 데이터 요청의 페이지 관리 방법을 변경하였다.

 

1.0.0-beta.2 

Paginate

  • page
  • per_page (default = 10)
GET /posts?_page=1&_per_page=25

 

0.17.4

Paginate

Use _page and optionally _limit to paginate returned data.

In the Link header you'll get first, prev, next and last links.

GET /posts?_page=7
GET /posts?_page=7&_limit=20

 

 

☀︎ 최신순으로 게시글 정렬하여 데이터 불러오기

?_sort=created_time&_order=desc 를 추가하여 게시글이 생성된 시간의 내림차순으로 정렬하도록 추가하였다.

* asc : 오름차순

* desc : 내림차순

const response = await feedInstance.get(`/feed?_sort=created_time&_order=desc&_page=${pageParam}&_limit=5`);

Sort

Add _sort and _order (ascending order by default)

GET /posts?_sort=views&_order=asc
GET /posts/1/comments?_sort=votes&_order=asc

For multiple fields, use the following format:

GET /posts?_sort=user,views&_order=desc,asc

 

 

☀︎ 구현한 모습

 

 

🥲느낀점

구글링해보면서 페이지네이션을 혼자 구현해보려고 끙끙댔었는데 막히는 부분이 많았고 결국 같은 팀에서 동일한 기능을 구현하신 팀원분께 많이 물어보면서 useInfiniteQuery를 적용해나갔다. 이 과정에서 혼자 고민하는 것도 좋지만 팀원에게 나의 상황을 공유하고 도움을 주고 받는 것도 효율적인 해결방법이라는 것을 깨닫게 되었고 여러 기능들을 계속 공부하면서 사용해보는 경험이 아주 중요하다는 걸 느끼게 되었다.