이전 캐싱데이터 렌더링 문제

강 진성·2024년 4월 10일
0

이모저모

목록 보기
4/5
post-custom-banner

데이터 캐싱문제


HealthyP 리팩토링 중
건강식 | 다이어트 | 벌크업 | 비건 등 대분류 카테고리에서 캐싱문제가 있다는 것을 발견하였다.

예를 들어, 건강식을 누르면 데이터가 캐싱되고 다음으로 다이어트 카테고리를 누른다.
그러면, 건강식의 데이터들이 잠깐 나온다음 다이어트 데이터들이 나온다.

이처럼, 이전 카테고리의 데이터들이 잠깐씩 렌더링 된다는 것이 문제였다. 원인이 무엇인가 하니, tanstack query 에서 쓰이는 캐싱로직이 잘못되었다는 것을 알게되었다.



[기존 코드]

const { data, status, isFetchingNextPage, fetchNextPage, hasNextPage } = useInfiniteQuery({
    queryKey: 'recipes',
    queryFn: callbackFn,
    initialPageParam: 1,
    getNextPageParam: (lastPage, allPages) => {
      const nextPage = lastPage.length ? allPages.length + 1 : undefined;
      return nextPage;
    },
  });

어디가 문제인가하니 querkKey 부분이 문제였다.
건강식, 다이어트, 벌크업, 비건 심지어 사진에는 보이지 않지만 북마크 페이지 조차 queryKeyrecipes 를 쓰고 있었다.

그래서, 5개의 페이지가 같은 데이터들을 캐싱하고 덮어씌우는 과정에 있었던 것이었다.

이 문제를 해결하기 위해, 각각 카테고리들에게 다른 queryKey 를 적용시킬 필요가 있었다.
다음은 수정한 코드이다.


[수정한 코드]

interface infinityCardProps {
  callbackFn: (pageParam: { pageParam: number | undefined }) => Promise<RecordModel[]>;
  title: string;
}

export function useInfinityCard({ callbackFn, title }: infinityCardProps) {

  const { data, status, isFetchingNextPage, fetchNextPage, hasNextPage } = useInfiniteQuery({
    queryKey: [title],
    queryFn: callbackFn,
    initialPageParam: 1,
    getNextPageParam: (lastPage, allPages) => {
      const nextPage = lastPage.length ? allPages.length + 1 : undefined;
      return nextPage;
    },
  });

props 로 title 을 추가해줬다. 그리고 useInfinityCard 를 쓰는 CategoryPage 에서 title 을 추가해줬다.


export function CategoryPage() {
  const { title } = useParams();

  async function getRecipeData({ pageParam = 1 }) {
    if (title === '오늘의 레시피') {
      const recordsData = await db.collection('recipes').getList(pageParam, 6, {
        expand: 'rating, profile',
        sort: '-views',
      });
      return recordsData.items;
    } else {
      const recordsData = await db.collection('recipes').getList(pageParam, 5, {
        expand: 'rating, profile',
        filter: `category = "${title}"`,
        sort: '-created',
      });

      return recordsData?.items;
    }
  }

  const { data, status, isFetchingNextPage, userData, ref } = useInfinityCard({
    callbackFn: getRecipeData,
    title: title || 'recipes',
  });

그 결과, useParamas() 에 의해 얻은 title 을 통해 각각의 카테고리에 알맞은 queryKey 를 배정해 줄 수 있었다.

그리고 각 queryKey 를 배정해준 결과, 이전 데이터들이 더이상 렌더링 되지 않고 정상적으로 현 카테고리들의 데이터들만 렌더링이 되었다.



결과


profile
완전완전완전초보초보초보
post-custom-banner

0개의 댓글