Next.js 13 App Router: router.push后revalidate未触发问题求助
Next.js 13 App Router:router.push后页面未触发重验证的解决方案
以下是针对你遇到的问题的几种可行解决办法:
方案1:使用router.refresh()强制刷新页面
在router.push后调用router.refresh(),可以强制客户端忽略缓存,重新从服务器拉取最新数据:
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); const { content } = formik.values; const success = await createPost(content); if (success) { await router.push("/blogs"); router.refresh(); // 触发页面重验证,获取最新数据 } };
方案2:配置fetchCache禁用缓存
在/blog/page.tsx中启用fetchCache配置,确保每次请求都跳过缓存:
export const revalidate = 0; export const fetchCache = "force-no-store"; // 强制禁用所有缓存 async function getData() { const postsDocRef = collection(firestore, "posts"); const q = query(postsDocRef, orderBy("createdAt", "desc"), limit(10)); const data = await getPosts(q); return data; } const Blogs = async (): Promise<JSX.Element> => { const posts = await getData(); return <BlogContainer posts={posts} />; }; export default Blogs;
方案3:改用客户端组件手动获取数据
将/blog/page.tsx改为客户端组件,通过useEffect在组件挂载时重新请求数据:
"use client"; import { useEffect, useState } from "react"; import { collection, query, orderBy, limit } from "firebase/firestore"; import { firestore } from "@/lib/firebase"; import { getPosts } from "@/lib/posts"; const Blogs = () => { const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { const fetchPosts = async () => { setLoading(true); const postsDocRef = collection(firestore, "posts"); const q = query(postsDocRef, orderBy("createdAt", "desc"), limit(10)); const data = await getPosts(q); setPosts(data); setLoading(false); }; fetchPosts(); }, []); if (loading) { return <div>加载中...</div>; } return <BlogContainer posts={posts} />; }; export default Blogs;
方案4:通过Server Action调用revalidatePath
如果createPost逻辑可以迁移到服务器端,使用Server Action配合revalidatePath直接标记页面缓存失效:
- 创建Server Action文件:
// app/actions/postActions.ts "use server"; import { revalidatePath } from "next/cache"; import { createPost } from "@/lib/posts"; export async function serverCreatePost(content: string) { const success = await createPost(content); if (success) { revalidatePath("/blogs"); // 强制让/blog页面缓存失效 } return success; }
- 在客户端调用该Action:
import { serverCreatePost } from "@/app/actions/postActions"; const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); const { content } = formik.values; const success = await serverCreatePost(content); if (success) { router.push("/blogs"); } };
推荐优先尝试方案1或方案4,这两种方式更贴合Next.js 13 App Router的设计逻辑。
内容的提问来源于stack exchange,提问作者Tom Fan
相关产品推荐
相关产品推荐

