ㅇㅇㅈ Blog

프론트엔드 수행중

0%

flatMap

원티드 3차 과제 중 무한 스크롤을 구현해야했다

react-queryuseInfiniteQuery를 이용해서 만들었다
intersectionObserver를 이용해 감지요소가 화면에 들어오면 api 요청을 하는건 기존에 했던 방식과 비슷하다

1
2
3
4
5
6
7
8
9
10
11
const { data, isLoading, hasNextPage, fetchNextPage, isFetching } = useInfiniteQuery(
[`${movieListQueryKey}`, `${pathname}`],
({ pageParam = 1 }) => getMovieListApi(movieListQueryKey, pageParam),
{
getNextPageParam: (lastPage, _) => {
const maxPages = lastPage.total_pages
const nextPage = lastPage.page + 1
return nextPage <= maxPages ? nextPage : undefined
},
},
)

useQuery와 비슷한 리턴값을 갖는다.
hasNextPage는 boolean으로 다음 페이지가 있는지,
fetchNextPage는 말그대로 다음 페이지를 요청해주는 메소드,
isFetching은 현재 api 요청중인지를 boolean으로 리턴해준다

getNextPageParam의 리턴값이 다음 요청때 쓰일 param을 리턴 시키면 pageParam 에 들어가서 다음 요청 파라미터로 사용된다.

getNextPageParam의 lastPage를 콘솔로 찍으면 실제 데이터가 들어있다.
여기서 다음페이지를 요청할때 필요한건 page값이니 이걸 +1 시켜서 리턴해준다

data를 콘솔로 찍으면 pagePrams에는 page값이 들어있고
pages에 array로 데이터가 들어있다.

화면에 뿌려지기 위한 데이터는 results 배열에 들어있으므로 이중 배열이 된다

그냥 map을 두번 돌아서 화면에 렌더링 할 수도 있지만
flatMap이란 메소드를 이용해서 작업하였다

1
2
3
4
5
const movieResults = useMemo(() => {
const results = data?.pages.flatMap(page => page.results)
return results || null
}, [data])

flatMap은 말그대로 flatmap을 합쳐 놓은거다 각 엘리먼트에 map수행 후, 결과를
flat으로 평탄화 해준다.