무한 스크롤 적용하기

회원가입 과정에서 사용자의 정보를 작성하고 사용자에게 책의 별점을 남길 수 있는 기능을 기획에 넣었다. 사용자가 선호하는 책 분야를 추천해주기 위해 도입한 과정이다.

알라딘 API를 사용하여 베스트셀러 기반 책을 불러와 사용자가 별점을 남길 수 있도록 구현하려고 한다. 이때 5개 이상의 별점(권당 1개의 별점)을 남겨야 한다.

사용자가 책에 별점을 등록하기 위해서 스크롤로 리스트를 볼 수 있으면 편리할 것 같다고 생각했다. 사용자에게 최소한의 클릭을 요구하고, 동작의 흐름을 끊지 않기 위해서 페이지네이션 보다는 무한 스크롤을 구현하는 것이 낫다고 판단했다.

Figma UI, 위 사진과 최대한 비슷한 레이아웃으로 구현하는 것을 목표로 한다.

Figma UI, 위 사진과 최대한 비슷한 레이아웃으로 구현하는 것을 목표로 한다.

무한 스크롤을 구현하기 위한 준비물은 아래와 같다.

<aside> 💡 react-intersection-observer: npm 라이브러리 useInfiniteQuery: react-query 라이브러리에서 제공하는 메서드 useMemo: use Hook

</aside>

react-intersection-observer: 페이지의 끝에 도달했는지 확인하기 위해

react-intersection-observer 라이브러리를 사용하여 컴포넌트가 화면에 보일 때 다음 페이지의 아이템 목록을 불러오려고 한다.

컴포넌트에 ref를 달아주면 화면에서 해당 컴포넌트가 보일 때 inView 값이 true가 된다. 이 inView를 사용해서 컴포넌트가 보일 때 특정 함수를 실행시킬 수 있는 로직을 구현할 수 있다.

import { useInView } from 'react-intersection-observer';

const { ref, inView } = useInView();

const func = () => {
	return(
		<div **ref={ref}**>안녕!</div>
	)
}

useInfiniteQuery: 데이터 호출하기

react-query에서 제공하는 useInfiniteQuery를 사용하여 데이터를 호출한다.

필자가 사용한 변수와 옵션에 대한 설명을 정리했다.

const {
        data, fetchNextPage, hasNextPage, isLoading, isFetchingNextPage
    } = useInfiniteQuery({
        queryKey:['evaluate-data'],
        queryFn: ({pageParam = 1}) => fetchBestSellerFunc(pageParam),
        select: (data) => ({ // pages, pageParams은 필수 반환값
            pages: data?.pages,
            pageParams: data.pageParams,
        }),
        getNextPageParam: (lastPage, allPages) => {
            const nextPage = allPages.length + 1;
            
            return lastPage.length === 0 ? undefined : nextPage;
        }
    })