
정말 많은 부분을 진행한 날이었다. 여러 곳을 동시다발적으로 수정했고, 다행히 프로젝트 제작을 잘 마무리한 것 같은 기분이 든다. 아직 끝은 아니지만!
힘들었던 부분은 아무래도 처음 접해봤던 useInfiniteQuery를 이용한 더보기 구현 부분... 다른 부분들은 그래도 어느 정도 해봤거나 감이 오는 부분이었기에 쉽게 끝났는데, 더보기 기능은 오후 시간을 거의 다 쓸 정도로 꽤 오랜 시간이 걸렸다.
아래는 자랑스러운(?) 더보기 기능 코드이다.
// 페이지 내 post 갯수
const ITEMS_PER_PAGE = 3;
// Home.jsx
// useInfiniteQuery
const {
data: posts,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
isPending,
error
} = useInfiniteQuery({
queryKey: ['infinitePosts'],
initialPageParam: 1,
queryFn: async ({ pageParam }) => {
const response = await getHomePosts(pageParam, ITEMS_PER_PAGE);
return {
posts: response.posts,
totalPages: Math.ceil(response.postsLength / ITEMS_PER_PAGE)
};
},
getNextPageParam: (lastPage, allPages, lastPageParam) => {
console.log(lastPage, allPages, lastPageParam);
if (lastPage.length === 0) {
return undefined;
}
const nextPage = lastPageParam + 1;
return nextPage <= lastPage.totalPages ? nextPage : undefined;
},
select: ({ pages }) => {
return pages.map((postsPerPage) => postsPerPage.posts).flat();
}
});
// 더보기 버튼
{hasNextPage && (
<StButtonBox>
<StMoreButton onClick={() => fetchNextPage()} disabled={isFetchingNextPage}>
더 불러오기
</StMoreButton>
</StButtonBox>
)}
// api.posts.js
export async function getHomePosts(pageParam, ITEMS_PER_PAGE) {
const { data: posts, error } = await supabase
.from('posts')
.select(`*, users(image_url, nickname)`)
.order('created_at', { ascending: false })
.range((pageParam - 1) * ITEMS_PER_PAGE, pageParam * ITEMS_PER_PAGE - 1);
const { data: allPosts } = await supabase.from('posts').select('*');
const postsLength = allPosts.length;
return { posts, postsLength };
}
기존에 튜터님께서 공유해주신 코드가 json.server를 이용하는 코드였기에 쓰는데 어려움이 있었고 계속 수정을 해보면서 진행했는데, 오히려 그것이 이 코드를 이해하는 데에 도움이 크게 되었다!
다만 아쉬운 점은, getHomePosts 함수에서 똑같은 supabase 데이터를 두 번이나 불러온다는 점이다. 좀 더 효율적인 방법이 분명 있을 것 같아서, 해당 부분은 기술 부채로 남겨두고 다시 진행해보아야겠다.
더보기 기능을 제작하다가 문제가 발생했다. 마이 페이지에 갔다가 다시 홈으로 가면, 알 수 없는 오류가 뜨면서 페이지가 열리지 않았다. 처음 보는 오류에 계속 질문을 했는데, queryKey가 겹치는 문제였다.
메인 페이지에서 사용한 queryKey는 posts였고, 마이 페이지에서 본인의 내 게시물을 불러오는 queryKey 역시도 posts였다. 허나 둘의 로직은 메인 페이지의 더보기 기능을 진행하면서 바뀌어있었고, 때문에 같은 queryKey인 경우, 마이 페이지에서 이미 달라진 queryKey를 메인 페이지로 이동했을 때 그대로 남아있기 때문에 오류가 뜬 것이다.
queryKey 네이밍의 중요성에 대해서 깨닫게 된 트러블 슈팅이었다.
바빴지만 그 속의 성취감이 기뻤던 날이었다. 지금 생각해보니, 문제를 해결하면서 아, 내가 이 맛이 좋아서 이 길을 선택했었지, 하는 생각을 다시금 할 수 있었던 것 같다.