Fittering 개발 기록 - Next.js 13 SSR data fetch 관련 트러블 슈팅

thumbzzero·2023년 9월 9일
0

구현 기능


메인 페이지 오늘의 랭킹, 카테고리별 상품 조회 기능에서 일정 기간에 한 번씩 Server Side Rendering으로 data fetch를 하여 업데이트 하도록 구현

트러블슈팅


문제

백엔드 측에서 상품 디비 업데이트를 해준 것을 확인하기 위해 일시적으로 revalidate 값을 0으로 설정해주어 SSR을 하도록 하였다.

기존에는 메인 페이지에 해당하는 page.tsx<ProductsRank /> 컴포넌트를 렌더링하고,

<ProductsRank /> 컴포넌트 내에서

export const revalidate = 3600 * 24;

와 같이 revalidate 값을 지정 후 data fetch를 해주었다.

빌드 후 확인해본 결과

page.tsx에서 바로 revalidate 값을 작성하고 data fetch를 한 카테고리 페이지(/categories/[[...categoryName]])와 다르게 메인 페이지(/)에서는 SSR 하는 페이지로 표시되지 않았다.

문제 원인

Next.js 공식 문서를 보면

위와 같이 export const revalidate를 지정해주는 것은 특정 route segment 내의 모든 fetch 요청에서 revalidate를 지정할 때 page.tsx에서 사용하고, 특정 fetch 요청에 대해서는 next.revalidate option을 사용해 지정해주는 것을 확인하였다.

메인 페이지에서 revalidate 값을 지정하고 싶은 것은 오늘의 랭킹 기능밖에 없으므로 next.revalidate을 사용하여 지정해주어야하는 것이었다.

해결

토큰이 필요없는 상품 미리보기 관련 API 요청 시 사용하는 커스텀 함수인 getProductPreviewWithoutToken() 함수를 기존에 매개변수로 url만 받아 처리하던 것에서 필요에 따라 options를 받아 처리할 수 있도록

export async function getProductPreviewWithoutToken(
  url: string,
  options?: RequestInit
): Promise<ProductPreview[]> {
  const response = await serverFetch(url, options);
  if (!response.ok) {
    return [];
  }
  return await response.json();
}

다음과 같이 수정한 다음,

async function fetchRank(gender: 'A' | 'M' | 'F') {
  return await getProductPreviewWithoutToken(`/products/rank/${gender}`, {
    next: { revalidate: 0 },
  });
}

코드를 위와 같이 수정 후 다시 빌드를 해보니


메인 페이지도 SSR 페이지로 된 것을 확인할 수 있었다.


업데이트된 상품을 제대로 불러오는 것을 확인한 뒤, revalidate 값을 다시 원래대로 수정해주었다. (24시간)

주의해야할 점은 next.revalidate 옵션을 사용할 때 정확한 number로 지정해주어야 한다. (초 단위)

async function fetchRank(gender: 'A' | 'M' | 'F') {
  return await getProductPreviewWithoutToken(`/products/rank/${gender}`, {
    next: { revalidate: 86400 },
  });
}

따라서 오늘의 랭킹 기능은 데이터 fetching 주기를 24시간으로 설정하고 싶으므로 3600 * 24이 아닌 86400으로 설정해주었다.

해당 정보는 공식 문서에 명시되어 있다.

0개의 댓글