Next.js中<Link>嵌套<a>导致两次历史栈记录的问题解决方案咨询
解决Next.js中嵌套导致历史栈重复及重复渲染问题
嘿,这个问题我之前也碰到过,确实是**和的跳转行为冲突**导致的——Link会通过Next.js的路由系统添加一条历史记录,而原生标签又会触发一次浏览器跳转,等于往历史栈里塞了两条相同的记录,所以返回需要点两次。结合你必须用标签加样式、还要避免相同路径重渲染的需求,给你两个可行的方案:
方案一:阻止标签的默认跳转行为
既然已经用处理路由了,那直接禁用的原生跳转就行。给标签添加onClick事件,调用e.preventDefault()阻止默认行为,这样就只会保留Link的路由跳转,不会生成重复的历史记录,同时相同路径点击也不会触发页面重渲染。
修改后的代码:
export default function Navigation() { const router = useRouter() const menus = [ { key: 'key1', title: 'title1', className: 'class1' }, { key: 'key2', title: 'title2', className: 'class2' }, ] return ( <div role="tablist"> {menus.map(({ key, title, className }) => ( <Link href={{ pathname: router.pathname, query: { menu: key } }} key={key}> <a className={className} role="tab" onClick={(e) => e.preventDefault()} // 阻止a标签的默认跳转 > <span>{title}</span> </a> </Link> ))} </div> ) }
方案二:直接给添加className(更简洁)
其实Next.js的组件最终渲染到页面上就是一个标签,所以你完全可以把className直接加到上,不需要额外嵌套标签。这样既满足了样式需求,又从根源避免了双重跳转的问题,相同路径点击也不会触发重渲染。
修改后的代码:
export default function Navigation() { const router = useRouter() const menus = [ { key: 'key1', title: 'title1', className: 'class1' }, { key: 'key2', title: 'title2', className: 'class2' }, ] return ( <div role="tablist"> {menus.map(({ key, title, className }) => ( <Link href={{ pathname: router.pathname, query: { menu: key } }} key={key} className={className} role="tab" > <span>{title}</span> </Link> ))} </div> ) }
为什么这两个方案能解决问题?
- 方案一:通过
preventDefault()禁用了的原生跳转,只让Next.js的Link路由系统处理页面切换,所以只会生成一条历史记录,相同路径点击时Link会判断路径一致,不会触发跳转和重渲染。 - 方案二:去掉了多余的嵌套,直接用Link生成带样式的标签,完全由Next.js路由控制,自然不会有双重跳转的问题,同时Link的内置逻辑会避免相同路径的重复渲染。
你可以根据自己的习惯选一个方案,亲测都能解决你的问题~
内容的提问来源于stack exchange,提问作者shapeless
相关产品推荐
相关产品推荐

