Page Router에서 데이터 페칭을 기억해봅시다!
Page 컴포넌트에서 사전 렌더링을 지시하는 함수를 이용해서 데이터를 페칭했습니다.
Page Router에서는 React Server Component의 개념이 없기에, 데이터를 가져올 때도 코드가 2번 실행되고,
가져온 데이터를 넘길 때도 Props로 일일이 넘겨야 한다는 단점이 존재했습니다.
(생각만 해도 복잡했음;)

코드로도 보기, 복잡하다🤯
export const getStaticProps = async (context: GetStaticPropsContext) => {
const id = context.params!.id;
const book = await fetchOneBook(Number(id));
if (!book) {
return {
notFound: true
}
};
return {
props: {
book,
},
};
};
export default function Page({
book,
}: InferGetStaticPropsType<typeof getStaticProps>) {
const router = useRouter();
//fallBack 인지 알려줌
if (router.isFallback) return "로딩 중입니다";
const { title, subTitle, description, author, publisher, coverImgUrl } = book;
return (
<div className={style.container}>
<div
className={style.cover_img_container}
style={{ backgroundImage: `url('${coverImgUrl}')` }}
>
<img src={coverImgUrl} />
</div>
<div className={style.title}>{title}</div>
<div className={style.subTitle}>{subTitle}</div>
<div className={style.author}>
{author} | {publisher}
</div>
<div className={style.description}>{description}</div>
</div>
);
}
App Router에서는 RSC를 이용해 이 단점을 해결할 수 있습니다!
서버 컴포넌트에서 async, await을 이용해 비동기 함수로 데이터를 페칭하면 됩니다.
데이터를 props를 이용해 넘길 필요 없이 필요한 곳에서 직접 호출하면 됩니다!

하지만 클라이언트 컴포넌트에서는 async를 사용할 수 없어요. 그 이유는 브라우저에서 동작 시 문제를 일으킬 수 있기 때문에 권장되지 않기 때문이죠. 이 점만 유의하면 됩니다.
또한 RSC로 필요한 페이지에서 직접 데이터를 가져와 사용할 수도 있어요.
async function AllBooks() {
const response = await fetch(`${process.env.NEXT_PUBLIC_API_SERVER_URL}/book`,
{ cache: "force-cache" }
);
if (!response.ok) {
return <div>오류가 발생했습니다. </div>
}
const allBooks: BookData[] = await response.json();
return (
<div>
{allBooks.map((book) => (
<BookItem key={book.id} {...book} />
))}
</div>
);
}
⭐️ 환경변수 설정 시 주의사항

NEXT_PUBLIC 접두사가 없으면 Next 에서 서버에서만 활용할 수 있는 private 변수로 취급해 클라이언트 컴포넌트에서 접근이 안됩니다.
꼭 접두사 붙이는 것을 주의하기.
fetch 메서드를 활용해 불러온 데이터를 Next 서버에서 보관하는 기능
영구적으로 데이터를 보관하거나, 특정 시간을 주기로 갱신시키는 것도 가능해요.
불필요한 데이터 요청의 수를 줄여서 웹 서비스의 성능을 크게 개선할 수 있어요.

cache : "force-cache" : 무조건 캐싱

cache :"no-store" : 캐싱 안함
next: { revalidate : 10 } : 10초에 한 번 캐시를 업데이트함, 마치 Page Router의 ISR 방식과 유사함

next: {tags: ['a']} : 요청에 의해 데이터를 최신화함. 마치 on-Demand Revalidate.
하나의 페이지를 렌더링하는 동안에 중복된 API 요청을 캐싱하기 위해 존재합니다.
하나의 페이지의 렌더링이 종료되면 모든 캐시가 소멸됩니다.

중복된 요청이 제거되었어요!

그런데, 그냥 중복된 요청을 보내지 않으면 되는데 굳이 중복을 제거하는 기능이 추가된 이유가 뭘까요?
그 이유는 App Router의 데이터 페칭 방법과 관련이 있어요.
Page Router에서는 서버 측에서만 데이터 페칭이 이루어졌지만,
App Router에서는 데이터가 필요한 컴포넌트에서 각각 데이터 요청을 보낼 수 있어, 중복 요청이 발생할 수 있습니다.

조금 더 어려운 용어로 설명하자면,
Request Memoization이 도입된 이유는 RSC 도입으로 중복된 API를 보낼 수 있게 되었기 때문이죠.
같은 API를 보낼 필요는 없기에 Next에서 자동으로 하나의 API만 보낼 수 있어요.
데이터 캐시는 벡엔드 서버로부터 불러온 데이터를 거의 영구적으로 보관하기 위해 사용됩니다.
Request Memoization은 하나의 페이지의 렌더링 동안만 보관되고 렌더링이 종료되면 캐시가 소멸됩니다. -> 영구적이지 X