何をする API か
router.refresh() は URL を変えずに、現在のルートの Server Component を再フェッチ します。ページ遷移は行いません。
router.push() / router.replace() | router.refresh() | |
|---|---|---|
| URL | 変わる | 変わらない |
| ページ遷移 | する | しない |
| Server Component の再フェッチ | 自動では行わない | 行う |
| Client state(useState など) | 保持される | 保持される |
なぜ push / replace の後に必要になるか
router.push() や router.replace() はクライアントサイドナビゲーションのため、Next.js のサーバーキャッシュを自動では更新しません。
たとえばログイン後に Cookie が発行されても、Server Component は古いキャッシュを返し続けることがあります。router.refresh() を合わせて呼ぶことで、Server Component が最新の Cookie を読み込んだ状態で再レンダリングされます。
"use client";
import { useRouter } from "next/navigation";
export default function LoginForm() {
const router = useRouter();
async function handleSubmit(e: React.FormEvent) {
e.preventDefault();
const res = await fetch("/api/login", { method: "POST", ... });
if (res.ok) {
router.replace("/dashboard"); // ページ遷移
router.refresh(); // Server Component を再フェッチして Cookie を反映
}
}
return <form onSubmit={handleSubmit}>...</form>;
}
遷移なしで状態だけ更新したい場合
ページを移動せずに Server Component のデータだけ更新したい場合にも使えます。
"use client";
import { useRouter } from "next/navigation";
export function LikeButton({ postId }: { postId: string }) {
const router = useRouter();
async function handleLike() {
await fetch(`/api/posts/${postId}/like`, { method: "POST" });
router.refresh(); // 同じページのまま Server Component を再フェッチ
}
return <button onClick={handleLike}>いいね</button>;
}
よくある誤解
Client state はリセットされない
router.refresh() は Server Component のデータを再フェッチするだけで、useState や useReducer の値はリセットされません。
// useState の count は refresh() を呼んでもリセットされない
const [count, setCount] = useState(0);
router.refresh(); // count は変わらない
完全なページリロードが必要な場合は window.location.reload() を使いますが、通常は router.refresh() で十分です。
URL は変わらない
router.refresh() はナビゲーション API ではありません。URL を変えたい場合は router.push() / router.replace() を使います。
// ❌ URL を変える目的では使えない
router.refresh(); // URL は変わらない
// ✅ URL を変えるなら push / replace
router.push("/new-page");
向いている場面
- ログイン・ログアウト後に Cookie の変化を Server Component に反映させたい
- フォーム送信後に同じページのリストを最新状態に更新したい
- 状態変更 API を呼んだ後に UI を再同期させたい(ただし遷移はしたくない)
router.push() / router.replace() / redirect() の使い分けは → router.push() vs router.replace() vs redirect()