Next.js 14 App Router静态导出时,如何在渲染时获取当前路由路径?
解决Next.js 14 App Router静态导出时标签栏active类服务端渲染问题
你可以通过让页面组件向布局传递当前激活标签的标识,在服务端渲染阶段就完成active类的判断,避免依赖客户端的usePathname。具体步骤如下:
1. 给每个页面组件添加自定义标识
在对应页面的组件中,给根元素加上data-active-tab属性,标识当前页面对应的标签:
app/post/[slug]/page.js(对应「All wins」标签):
export default function PostPage() { return <div data-active-tab="">// 页面内容</div>; }
app/post/[slug]/top/page.js(对应「Top wins」标签):
export default function TopPage() { return <div data-active-tab="top">// 页面内容</div>; }
app/post/[slug]/stats/page.js(对应「Statistics」标签):
export default function StatsPage() { return <div data-active-tab="stats">// 页面内容</div>; }
2. 在布局组件中读取标识并设置active类
在app/post/[slug]/layout.js(服务端组件)中,通过React的Children API获取页面组件的自定义属性,动态判断并添加active类:
import { Children, isValidElement } from 'react'; import Link from 'next/link'; export default function PostLayout({ children, params }) { let activeTab = ''; // 获取唯一的子页面元素 const childElement = Children.only(children); // 读取自定义属性 if (isValidElement(childElement)) { activeTab = childElement.props['data-active-tab'] || ''; } return ( <> <div className="tabs"> <Link href={`/post/${params.slug}`} className={activeTab === '' ? 'active' : ''} >All wins</Link> <Link href={`/post/${params.slug}/top`} className={activeTab === 'top' ? 'active' : ''} >Top wins</Link> <Link href={`/post/${params.slug}/stats`} className={activeTab === 'stats' ? 'active' : ''} >Statistics</Link> </div> {children} </> ); }
原理说明
静态导出时,每个页面都会和布局一起预渲染。通过页面组件传递的自定义标识,布局可以在服务端渲染阶段就确定当前激活的标签,生成的静态HTML中直接包含active类,完全不需要客户端处理,避免了路由判断的客户端依赖和页面闪烁问题。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

