NextJS 13:跳转至带搜索参数的404页面后,回退前页仍显示404
问题分析
在Next.js 13.4.9的App Router中,当服务器组件调用notFound()触发not-found页面后,客户端路由缓存会保留该路由的"未找到"状态。当通过后退按钮返回/products(无tag=dummy参数)时,客户端会复用缓存的状态,导致仍然展示not-found页面,即使已设置dynamic: 'force-dynamic'。
解决方案
方案1:客户端监听路由变化并强制刷新
在/products页面中添加一个客户端组件,监听搜索参数变化,当回到有效路由时调用router.refresh()清除缓存状态:
- 创建客户端组件
RouteRefresher.js:
'use client'; import { useRouter, useSearchParams } from 'next/navigation'; import { useEffect } from 'react'; export default function RouteRefresher() { const router = useRouter(); const searchParams = useSearchParams(); useEffect(() => { const tag = searchParams.get('tag'); // 当路由回到无tag的/products时,触发刷新 if (!tag) { // 延迟执行确保路由状态已更新 setTimeout(() => router.refresh(), 0); } }, [searchParams, router]); return null; }
- 修改
/products/page.js引入该组件:
import Link from 'next/link'; import { notFound } from 'next/navigation'; import RouteRefresher from './RouteRefresher'; export const dynamic = 'force-dynamic'; export default function Page({ searchParams }) { if (searchParams['tag'] === 'dummy') { notFound(); } return ( <div> <h1 className='mb-4'>Products Page</h1> <Link href='/products?tag=dummy' className='bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full'> Filter by tag dummy </Link> <p>{JSON.stringify(searchParams)}</p> <RouteRefresher /> </div> ); }
方案2:改用客户端条件渲染替代notFound()
如果不需要触发全局的not-found.js页面,可以将页面改为客户端组件,直接在组件内判断搜索参数并渲染对应内容,避免框架缓存not-found状态:
'use client'; import Link from 'next/link'; import { useSearchParams } from 'next/navigation'; export default function ProductsPage() { const searchParams = useSearchParams(); const tag = searchParams.get('tag'); if (tag === 'dummy') { return ( <div> <h2>Not Found</h2> <p>The requested product filter is not available.</p> <Link href='/products' className='mt-4 inline-block bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full'> Back to Products </Link> </div> ); } return ( <div> <h1 className='mb-4'>Products Page</h1> <Link href='/products?tag=dummy' className='bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full'> Filter by tag dummy </Link> <p>{JSON.stringify(Object.fromEntries(searchParams))}</p> </div> ); }
方案3:升级Next.js版本
该问题可能是Next.js 13.4.9的已知bug,尝试升级到13.x系列的最新稳定版本(如13.5.x),框架可能已经修复了路由缓存与notFound()的兼容问题。
内容的提问来源于stack exchange,提问作者Brock's Animation
相关产品推荐
相关产品推荐

