두개의 차이점
안녕하세요, 아래 ISR에 대해서 질문드렸었는데, nextjs 에서 2가지 구현 방법이있다고 해서
두가지가 어떤 차이점이 있고 어떻게 활용하는게 좋을지 궁금해서 질문드립니다!
1번 방법 = fetch API 의 revlidate를 활용하여 ISR 구현
import ProductList from "@/component/ProductList";
import { getQueryClient } from "@/component/TanstackQueryOption";
import { getProducts } from "@/fetch/getProducts";
import { dehydrate, HydrationBoundary, QueryClient } from "@tanstack/react-query";
import Image from "next/image";
export default async function ProductPage () {
const queryClient = getQueryClient();
await queryClient.prefetchQuery({
queryKey:['products'],
queryFn: getProducts,
})
return (
<>
<section className='visual-sec'>
<Image src="/visual.png" alt="visual" width={1920} height={300}/>
</section>
<section className="product-sec">
<h2>상품 리스트</h2>
<HydrationBoundary state={dehydrate(queryClient)}>
<ProductList />
</HydrationBoundary>
</section>
</>
)
}import {
isServer,
QueryClient,
defaultShouldDehydrateQuery,
} from '@tanstack/react-query'
function makeQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
staleTime: 10 * 1000,
},
dehydrate: {
shouldDehydrateQuery: (query) =>
defaultShouldDehydrateQuery(query) ||
query.state.status === 'pending',
},
},
})
}
let browserQueryClient: QueryClient | undefined = undefined
export function getQueryClient() {
if (isServer) {
return makeQueryClient()
} else {
if (!browserQueryClient) browserQueryClient = makeQueryClient()
return browserQueryClient
}
}'use client'
import { getQueryClient } from '@/component/TanstackQueryOption';
import {
QueryClientProvider,
} from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { ReactNode } from 'react'
export default function TanstackQueryProvider({ children }: { children: ReactNode }) {
const queryClient = getQueryClient()
return (
<QueryClientProvider client={queryClient}>
{children}
<ReactQueryDevtools
initialIsOpen={true}
/>
</QueryClientProvider>
)
}
export const getProducts = async () => {
const res = await fetch(`http://localhost:9090/api/products`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
next: {
revalidate: 10,
}
});
const data = await res.json();
const currentTime = new Date().toLocaleTimeString('ko-KR', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
fractionalSecondDigits: 3,
hour12: false,
});
if (typeof window === "undefined") {
console.log('fetch products', 'server', currentTime);
console.table(data);
} else {
console.log('fetch products', 'client', currentTime);
console.table(data);
}
if(!res.ok) {
throw new Error("Failed to fetch products");
}
return data;
}
2번 방법 = export const revalidate 로 시간 설정 후 fetch로 받은 data 값을 바로 렌더링 시키기
import Product from "@/component/Product";
import styles from '@/component/ProductList.module.css';
import Image from "next/image";
export const revalidate = 10;
export default async function Product2Page() {
const data = await fetch('/api/products');
const products = await data.json();
console.log(revalidate, 'Product2Page');
return (
<>
<section className='visual-sec'>
<Image src="/visual.png" alt="visual" width={1920} height={300}/>
</section>
<section className="product-sec">
<h2>상품 리스트</h2>
<div className={styles.productList}>
{products.map((product: any) => (
<Product key={product.item_no} product={product} />
))}
</div>
</section>
</>
)
}
2개다 ISR로 구현되며, 1번 방법은 Data Cache 캐싱 매커니즘을 활용하고,
2번 방법은 Full Router Cache 캐싱 매커니즘을 활용한다의 차이점으로 생각이 드는데,
이 외에 다른 차이점과 실제 개발을 하면서 선호되는 방식이 따로 있을까요? 해당 페이지만 보았을때는 2번 방법으로 해도 어차피 주기적으로 다시 생성해서 최신 데이터를 반영하면 복잡하게 react-query를 사용하고, Hydration을 하면서 데이터를 동기화할 필요가 있나 싶어서 어떻게 사용해야할지 감이 안잡히네여
답변 1
0
2번 방법으로 하면 페이지는 10초마다 리밸리데이트하더라도 fetch의 데이터는 영구적으로 캐싱일 것 같습니다. 프로덕트 목록이 업데이트 되는 것이라면 1번 방식을 해야할 것 같네요.
0
다시 문서 읽어보니까 const revalidate는 default value가 Infinity인데 fetch revalidate는 기본값이 없네요. 그러면 지금 상황에서는 둘이 똑같은 게 맞습니다. 1번에서는 fetch revalidate가 const revalidate를 낮추고, 2번에서는 const revalidate 값을 fetch revalidate가 따라가네요.
참고로 개발모드에서는 페이지 캐시가 작동하지 않으니 테스트할 때 유의하셔야 합니다.
캡처링부분 질문있습니다.
0
88
2
깃에 소스코드를 찾을 수 없습니다.
0
121
2
useInfiniteQuery promise와 react use 사용시 페이지 무한 로딩
0
100
1
import 파일 경로를 찾지 못 해서 에러가 발생합니다.
0
119
2
css 라이브러리 추천 부탁드립니다
0
153
2
팔로우 추천 목록이 빈 배열로 들어옵니다.
0
137
1
게시물 업로드 시 userId가 undefined로 들어가는 오류
0
121
1
useSuspenseQuery 사용 시 SSR 401 이슈 관련
0
177
1
리액트 쿼리 useinfinitequery 무한스크롤 구현 시 페이지가 이동할 경우 데이터가 보존되게 할 수 있나요??
0
192
3
폴링이 필요없는 이유
0
100
2
next Request Memoization과 react cache
0
114
2
seo 최적화 기준은 데이터 fetching인가요 아님 데이터 렌더링인가요?
0
90
2
next.js 서버fetch 에러 fallback ui 구현 방법
0
174
2
프레임워크 여론 파악법
0
128
2
필터옵션이 많은 페이지에서 서버 fetch를 하는게 맞는걸까요??
0
109
2
서버 fetch suspense 로 감싸고 새로고침 시 잠시 빈 화면이 노출된 후 fallback ui가 노출됩니다.
0
110
2
template.tsx 내 서버fetch 응답값과 클라이언트 컴포넌트 상태값 싱크가 맞지 않는 이슈
0
70
2
Auth.js 사용 시 authorize 함수가 호출되지 않습니다
0
135
2
next.js 에서 로그인에 관하여
0
144
1
Next의 route handler에 대한 질문이 있습니다.
0
102
2
게시판 리스트 만들때 use client를 어디서부터 집어넣어야할지 모르겠습니다
0
103
2
프라이빗 폴더를 해야 하는 이유가 모호한 것 같아요.
0
88
2
vanilla-extract 못찾는 문제
0
235
2
fetch 캐싱과 revalidate 관련
0
93
2





