작성
·
41
0
안녕하세요! 좋은 Next.js 강의 덕분에 열심히 배워나가고 있는 학생입니다. 😀
다름이 아니라 revalidateTag를 사용했을 때, 첫 번째 인수로 전달한 태그 값을 가지는 데이터 캐시가 재검증된다고 이해했는데요!
제가 revalidateTag의 인수와 data fetch에 사용되는 옵션의 태그 값을 다르게 세팅해봤는데도 갱신이 되어서요.
제가 잘못 이해한 걸까요..?? 이 부분이 이상해서 질문 남깁니다.
아래는 제가 작성한 코드입니다!
createReviewAction
export async function createReviewAction(formData: FormData) {
const bookId = formData.get('bookId')?.toString();
const content = formData.get('content')?.toString();
const author = formData.get('author')?.toString();
if (!bookId || !content || !author) {
return;
}
// JSON.stringify 객체를 문자열 형태로 직렬화 해서 보내줘야 함
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_API_SERVER_URL}/review`,
{
method: 'POST',
body: JSON.stringify({ bookId, content, author }),
},
);
revalidateTag(`revew-${bookId}`); // 일부로 오타 냄
} catch (error) {
console.error(error);
return;
}
}
ReviewList 컴포넌트
async function ReviewList({ bookId }: { bookId: string }) {
const response = await fetch(
`${process.env.NEXT_PUBLIC_API_SERVER_URL}/review/book/${bookId}`,
{ next: { tags: [`review-${bookId}`] } },
);
if (!response.ok) {
throw new Error(`Review fetch faild: ${response.statusText}`);
}
const reviews: ReviewData[] = await response.json();
return (
<section>
{reviews.map((review) => (
<ReviewItem key={`review-item-${review.id}`} {...review} />
))}
</section>
);
}
답변 3
0
강의 들으면서 다른 분들은 어떤 부분이 궁금한지 Q&A를 보던 중, 저도 실험을 해보고 공식문서를 찾아봤습니다.
공식 문서에서는
“
revalidateTag
invalidates all entries associated with that tag”
“When usingfetch
, you have the option to tag cache entries with one or more tags. Then, you can callrevalidateTag
to revalidate all entries associated with that tag.”
라고 되어 있어서, 같은 태그 문자열이 정확히 일치해야 캐시 무효화가 일어난다고 설명되어 있습니다.
그런데 실제로 실험해보면, 태그의 접두사 부분(review-
, book-review-
등)은 달라도 ${bookId}
식별자가 같으면 동일한 캐시 그룹으로 인식되어 재검증이 되는 것처럼 보입니다.
즉, 태그명 전체보다 데이터를 구분할 수 있는 식별자(bookId) 가 캐시 그룹을 구분하는 핵심 역할을 하는 것처럼 동작하는 것 같습니다. 혹시 내부적으로 fetch URL 단위 캐시와 태그 캐시가 연결되어 있어서 이런 결과가 나오는 걸까요?
안녕하세요 정환님 실제로 테스트도 해주시고 답변해주셔서 감사합니다 ㅠㅠ, 백서버에 review.controller.js @Get에서 아래처럼 로깅 찍고 테스트 해봤을 때
findReviews(@Param('bookId') bookId: number) { console.log(`[FETCH LOG] GET /review/book/${bookId} 요청 발생`); return thiseviewService.findBookReviews(bookId); }
revalidateTag주석처리 했을 때는 당연히 재검증이 안되어 새로고침해야 로깅이 떴고revalidateTag에 서버 액션에 아래처럼 ${bookId}만 일치시키고 앞의 접두사 부분은 엉뚱한걸로 했을 때도 재검증이 되더라고요
revalidateTag(`아에오우-${bookId}`);
참고로 page 태그는 강의내용처럼 동일합니다
제가 실수한 부분이 있을 것 같지만 제딴에 이것저것 테스트해봐도 도저히 모르겠어서요 ㅠㅠ 천천히 답주셔도 됩니다!
async function ReviewList({ bookId }: { bookId: string }) {
const response = await fetch(
`${process.env.NEXT_PUBLIC_API_SERVER_URL}/review/book/${bookId}`,
{ next: { tags: [`review-${bookId}`] } }
);
안녕하세요 이정환입니다.
아! 이유를 찾았습니다. 뭔가 버그처럼 보이는 동작인데 아래의 공식문서 내용을 보시면 풀라우트 캐시를 무효화 하는데에는 2가지 방법이 있다고 하면서 그 중 첫번째 방법으로 Revalidating Data를 소개하고 있습니다.
https://nextjs.org/docs/app/guides/caching#invalidation
위 내용에 따르면 Revalidating Data가 진행 될 경우(revalidateTag 등의 메서드를 통하여) 서버 컴포넌트를 다시 렌더링 하여 새로운 렌더링 아웃풋을 제공한다고 합니다.
따라서 revalidateTag를 호출하고 "아에이오우" 같은 존재하지 않는 태그를 전달한다고 해도 어찌되었든 revalidate 요청이 발생하긴 한것이므로 페이지 자체가 리렌더링 되는 것으로 보입니다.
정확한 확인을 위해 서버 액션 내부의 revalidateTag 메서드 자체를 제거하고 실험해보니 이 경우에는 아예 리렌더링이 발생하지 않네요
버그처럼 보이는 이상한 동작(?) 이지만 ... 결과적으로 이런 이유에서 이렇게 동작하는 것 같습니다.
0
안녕하세요 이정환입니다.
ReviewList에서 호출한 fetch 메서드의 데이터 캐시가 혹시 어떤 타이밍에 검증되나요?
PS.
참고로 개발모드로 동작 중에는 페이지를 강하게 새로고침 했을 때 데이터가 강제로 검증됩니다.
혹시 개발모드로 실험해보셨다면 프로덕션 모드로도 다시 실험해보시면 문제 없이 동작할 수 있습니다.
리뷰 내용을 작성하고, '작성하기' 버튼을 클릭했을 때 입니다!
ReviewList 컴포넌트 내에서 호출하는 API의 tag를 review-bookId를 설정해두고, 작성하기 버튼 클릭 시 createReviewAction 실행 -> 내부에서 리뷰 등록 API 호출 -> revalidateTag('review-bookId')를 호출하면 재검증이 되는 것으로 이해했는데, 태그 값이 달라도 재검증이 되는 것 같아서 질문드렸어요.
프로덕션 모드로 실행해도 동일하게 재검증이 되네요......
안녕하세요 이정환입니다.
오잉 ..!? 이상하네요 정확한 원인 파악을 위해서는 전체 프로젝트 코드를 받아 제가 확인해봐야 할 것 같습니다. 깃허브 or 구글 드라이브 링크로 보내주시면 살펴볼게요!
0
안녕하세요, 인프런 AI 인턴입니다. fud3725님.
revalidateTag
함수의 동작에 대해 궁금하신 점에 대해 답변드리겠습니다.
revalidateTag
함수는 특정 태그와 연관된 캐시 데이터를 재검증하여, 변경된 데이터가 클라이언트에게 전달되도록 하는 역할을 합니다. 이를 통해 특정 데이터만을 효율적으로 업데이트할 수 있습니다.
작성해주신 코드에서 revalidateTag
사용시 오타를 의도적으로 발생시켰다고 하셨는데, 그럼에도 캐시가 갱신되는 것은 의도하지 않은 상황입니다.
revalidateTag(`revew-${bookId}`); // 일부로 오타 냄
여기서 revew-${bookId}
대신 review-${bookId}
라는 정확한 태그명을 전달해야만 해당 태그로 캐싱된 데이터가 요청 시 새롭게 갱신됩니다.
반대로, ReviewList
컴포넌트에서는 올바른 태그(review-${bookId}
)를 사용하고 있으므로, fetch 요청 시마다 정상적으로 재검증이 이루어져야 하지만, 오타 때문에 이를 기대할 수 없게 됩니다. 해당 코드의 동작이 일관되지 않다면, 정확한 태그명 사용을 확인하는 것이 우선일 것입니다.
createReviewAction
과 ReviewList
컴포넌트 모두 동일한 태그 규칙을 사용해야 합니다.revalidateTag
함수 호출 시 태그명을 정확하게 맞춰주세요.next: { tags: [...] }
옵션이 의도대로 설정되어 있는지, 서버 설정을 포함해 한 번 더 점검해보세요.관련 예제나 설정에 대해서는 Next.js 공식 문서의 Data Fetching 섹션을 참조하시면 도움이 될 것입니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
안녕하세요 이정환입니다.
방금 실험해 본 결과 프로덕션 모드에서는 정확히 일치하는 tag의 fetch만 재검증 되는것으로 확인되었습니다.
이를 확인해보시려면 제공해드린 백엔드 서버에 간단한 로깅 기능을 추가하신 다음 Next.js 앱을 빌드 후 동작시켜보시는걸 추천드립니다.
혹시 동일한 조건에서 테스트 하셨음에도 문제가 발생한다면 바로 답글로 알려주세요 !_!