Next.js 13启用appDir后如何实现Shallow Router Push?
在Next 13 App Router中实现类似Shallow路由的效果
在App Router(appDir)中,官方没有提供和Pages Router中完全一致的shallow: true选项,但可以通过客户端组件的路由操作实现仅修改URL、不触发全页面刷新的效果,核心要点如下:
关键前提:使用客户端组件
只有在客户端组件中执行路由操作,才能避免触发服务器端渲染导致的全页面刷新。在组件顶部添加'use client'指令标记为客户端组件:
'use client'; import { useRouter, usePathname, useSearchParams } from 'next/navigation';
实现代码示例
以下代码可以复刻你在Pages Router中实现的toggleStatic功能,仅修改URL查询参数,不会触发全页面刷新:
'use client'; import { useRouter, usePathname, useSearchParams } from 'next/navigation'; export default function ToggleStaticButton() { const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); const toggleStatic = () => { // 复制当前查询参数(原searchParams是只读对象,不能直接修改) const newSearchParams = new URLSearchParams(searchParams); if (newSearchParams.has('static')) { newSearchParams.delete('static'); } else { newSearchParams.set('static', ''); } // 拼接新的URL const queryString = newSearchParams.toString(); const newUrl = queryString ? `${pathname}?${queryString}` : pathname; // 执行客户端导航,不会触发全页面刷新 router.push(newUrl); }; return ( <button onClick={toggleStatic}> {searchParams.has('static') ? '移除static参数' : '添加static参数'} </button> ); }
原理说明
- App Router中,客户端组件内调用
router.push/router.replace时,导航逻辑完全在客户端执行,不会触发服务器端的页面重新渲染,也不会刷新整个页面,这和Pages Router中shallow: true的核心效果一致。 - 使用
URLSearchParams操作查询参数是更安全的方式,避免手动拼接字符串导致的格式错误。 - 若不需要新增历史记录条目,可以替换为
router.replace(newUrl),对应Pages Router中router.replace(..., { shallow: true })的效果。
常见问题排查
如果你的代码仍触发全页面刷新,大概率是以下原因:
- 没有给执行路由操作的组件添加
'use client'指令,导致组件以服务器组件运行,路由操作会触发服务器端导航。 - 跳转的目标页面是静态生成(SSG)且未配置动态路由参数支持,这种情况下可能会触发页面重新加载,但查询参数变化一般不会影响静态页面的渲染。
内容的提问来源于stack exchange,提问作者brandonscript
相关产品推荐
相关产品推荐

