[디버깅] React Query + FireStore 페이지네이션에서 동일한 페이지 보이는 버그(feat. Zustand)

YouGyoung·2024년 4월 14일
0

버그 내용

페이지 크기가 2라고 했을 때, 1페이지가 아래 사진처럼 표시된다고 하면 2페이지도 동일하게 1페이지의 데이터가 표시되는 버그가 나타났습니다.

원인

FireStore 데이터를 페이지처리 하려면 마지막 문서를 들고 있어야 했는데 아래 코드와 같이 useState를 사용해 마지막 문서를 들고 있었습니다.

export default function Board({ params }: { params: { pageNumber: number } }) {
    const [page, setPage] = useState(params.pageNumber);
    
    const [lastDoc, setLastDoc] = useState<
        QueryDocumentSnapshot<DocumentData> | undefined
    >(undefined);

    const { data, isFetching } = useQuery<PostQueryResult>({
        queryKey: ['posts', 'all', page],
        queryFn: async () => await getPosts(page - 1, lastDoc),
        placeholderData: keepPreviousData,
        staleTime: 500,
    });

    useEffect(() => {
        setLastDoc(data?.lastDoc);
        console.log(lastDoc);
    }, [data]);

   
    ...

페이지네이션의 각 페이지 버튼은 Link 컴포넌트로 구현되어 있는데, 이 Link를 통해 params가 변경되면 state가 초기화되는 게 문제였습니다.

해결

Zustand를 설치하고, 마지막 문서를 전역 저장소에 저장하여 해결했습니다.

/* /app/store.ts */
import create from 'zustand';
import { DocumentData, QueryDocumentSnapshot } from 'firebase/firestore';

type Store = {
    lastDoc: QueryDocumentSnapshot<DocumentData> | undefined;
    setLastDoc: (doc: QueryDocumentSnapshot<DocumentData>) => void;
};

const useStore = create<Store>()(set => ({
    lastDoc: undefined,
    setLastDoc: doc => set({ lastDoc: doc }),
}));

export default useStore;



/* /app/board/page.tsx */

import useStore from '@/app/store';
export default function Board({ params }: { params: { pageNumber: number } }) {
    const [page, setPage] = useState(params.pageNumber);

    const { lastDoc, setLastDoc } = useStore();
    const { data, isFetching } = useQuery<PostQueryResult>({
        queryKey: ['posts', 'all', page],
        queryFn: async () => await getPosts(page - 1, lastDoc),
        placeholderData: keepPreviousData,
        staleTime: 500,
    });

    useEffect(() => {
        if (data?.lastDoc) setLastDoc(data?.lastDoc);
        console.log(lastDoc);
    }, [data]);
...

마치며

최근 어떤 한 블로그 포스팅에서 '상태 관리 라이브러리 없이 React Query만으로 충분히 해결할 수 있는 문제에 굳이 상태 관리 라이브러리를 쓰지 않아야 한다_' 라는 내용을 봤었습니다.

지난 번 쇼핑몰 프로젝트 리팩토링을 하면서 상태 관리 라이브러리가 없어도 되겠는데 라는 생각을 하긴 했었습니다.

그래서 이번 영화 커뮤니티 프로젝트에서는 정말 필요할 때 Zustand를 도입해야지 라는 생각을 가지고 있었는데, 딱 필요한 시점이 와버렸네요ㅎㅎ

상태 관리 라이브러리를 최대한 안 사용하기 위해서 그 부분으로는 생각을 하지 않고 있던 터라 버그 해결에 시간이 오래 걸렸습니다.🥲

프로젝트 진행의 중후반부에 상태 관리 라이브러리를 도입하기엔 너무 번거롭지 않을까 라는 생각을 했었는데(Redux의 영향..) Zustand는 정말이지 와우..놀랍도록 설정 코드가 짧고, 사용법도 매우 쉬웠습니다.

왜 요즘 사람들이 Redux에서 Zustand로 많이 넘어가지는 알겠더군요!

이번 버그를 통해 상태 관리 라이브러리가 왜 필요한지 한 번 더 알게된 거 같아 기분이 좋습니다 ㅎㅎㅎ

profile
프론트엔드 개발자

0개의 댓글

관련 채용 정보