
보통 폼을 제출한 후 강제로 새로고침(window.location.reload())을 해야 변경된 데이터를 확인할 수 있습니다. 하지만 Next.js의 revalidateTag 또는 revalidatePath를 사용하면 새로고침 없이도 자동으로 변경된 데이터를 화면에 반영할 수 있습니다.
이 글에서는 Next.js의 서버 액션(Server Action)을 사용하여 리뷰를 제출한 후, 자동으로 리뷰 목록을 업데이트하는 방법을 설명하겠습니다.
ReviewEditor.tsx)'use client';
export default function ReviewEditor({ bookId }: { bookId: string }) {
return (
<form action={createReviewAction}>
<input name="bookId" value={bookId} hidden readOnly />
<textarea name="content" required placeholder="리뷰 내용을 입력하세요." />
<button type="submit">제출</button>
</form>
);
}
✔ 사용자가 폼을 입력하고 제출하면 createReviewAction이 실행됩니다.
create-review-action.ts)'use server';
import { revalidateTag } from 'next/cache';
export async function createReviewAction(formData: FormData) {
const bookId = formData.get('bookId')?.toString();
const content = formData.get('content')?.toString();
if (!content) return;
try {
await fetch(`${process.env.NEXT_PUBLIC_SERVER_API_URL}/review`, {
method: 'POST',
body: JSON.stringify({ bookId, content }),
});
// ✅ 해당 리뷰 데이터만 재검증하여 새로고침 없이 자동 반영
revalidateTag(`review-${bookId}`);
} catch (err) {
console.error(err);
}
}
✔ revalidateTag(\review-${bookId}`)`를 호출하면, 해당 태그와 연결된 데이터만 새로고침 없이 자동으로 갱신됩니다. (자세히 후술)
ReviewList.tsx)export default async function ReviewList({ bookId }: { bookId: string }) {
const response = await fetch(
`${process.env.NEXT_PUBLIC_SERVER_API_URL}/review/book/${bookId}`,
{ next: { tags: [`review-${bookId}`] } }
);
if (!response.ok) {
throw new Error(`리뷰 가져오기 실패: ${response.statusText}`);
}
const reviews = await response.json();
return (
<section>
{reviews.map((review) => (
<div key={review.id}>
<strong>{review.author}</strong>
<p>{review.content}</p>
</div>
))}
</section>
);
}
✔ fetch() 요청 시 { next: { tags: [\review-${bookId}`] } }`를 추가하면 해당 태그를 가진 데이터가 변경될 때 자동으로 다시 불러옵니다.
revalidate 활용 방법revalidatePath)import { revalidatePath } from 'next/cache';
revalidatePath(`/book/${bookId}`);
✔ 해당 페이지를 다시 생성하여 갱신합니다.
✔ 하지만 해당 페이지에 캐싱해둔 다른 데이터도 함께 사라지는 문제가 발생할 수 있습니다.
revalidatePath("/book/[id]", "page");
✔ /book/1, /book/2, /book/3 등 book 폴더의 [id].tsx로 접속 가능한 모든 페이지 데이터를 갱신합니다.
revalidatePath("/(with-searchbar)", "layout");
✔ /(with-searchbar) 폴더 내의 layout.tsx가 적용되는 모든 페이지가 새로 생성됩니다.
revalidatePath("", "layout");
✔ 전체 데이터를 재검증하여 모든 캐시를 갱신합니다.. (일반적으로 사용 X)
revalidateTag)const response = await fetch('path'), {next: {tags: [`review-${id}`]}};
revalidateTag(`review-${bookId}`);
✔ 특정 태그와 연결된 데이터만 갱신 (가장 효율적인 방법!)
✅ Next.js의 revalidateTag를 활용하면 변경된 데이터를 바로 화면에 렌더링할 수 있음.
✅ 전체 페이지를 다시 불러오지 않고 필요한 데이터만 갱신하므로 성능이 향상됨.
✅ 상황에 따라 revalidatePath와 revalidateTag를 적절히 조합하면 더 효과적인 데이터 갱신이 가능.
✅ 단, pull route를 삭제할 뿐 새롭게 생성하지는 않음. 다음 차례의 접속 요청이 들어오면 그제서야 생성함 -> 가장 최신 데이터를 보여주기 위해!