Next.js 13路由带数据请求页面滚动位置未重置问题求助
Next.js 13 路由滚动位置异常问题解决方案
在Next.js 13的App Router中,跳转至带有初始数据请求的服务器组件页面时,页面会保留上一页的滚动位置;但跳转至无初始数据请求的页面时,新页面会正常滚动到顶部。已尝试Reddit相关方案但未解决。
解决方案1:客户端组件强制滚动到顶部
创建一个专用的客户端组件监听路由变化,自动触发滚动到顶部:
// components/ScrollToTop.tsx "use client"; import { useEffect } from "react"; import { usePathname } from "next/navigation"; export default function ScrollToTop() { const pathname = usePathname(); useEffect(() => { // 路由切换时滚动到页面顶部 window.scrollTo({ top: 0, behavior: "instant" }); }, [pathname]); return null; }
在带数据请求的目标页面(服务器组件)中引入该组件:
// app/[id]/page.tsx type Props = { params: { id: string } } import ScrollToTop from '@/components/ScrollToTop'; async function Page({ params: { id } }: Props) { const capsuleData = await getCapsule(id); return ( <> <ScrollToTop /> {/* 页面原有内容 */} </> ) } export default Page
解决方案2:配置Next.js实验性滚动恢复(辅助方案)
在next.config.js中启用实验性滚动恢复配置,部分场景下可自动修复:
// next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { experimental: { scrollRestoration: true, }, } module.exports = nextConfig
注意:该配置为实验性功能,可能无法覆盖所有复杂场景,建议配合方案1使用。
解决方案3:跳转时手动触发滚动
在跳转组件的点击事件中,手动触发滚动到顶部:
// components/CapsuleCard.tsx "use client" import { useRouter } from "next/navigation"; function CapsuleCard({ title, icon, stickerValue, capsulePrice, hoverAnimation, detailPage }: Props) { const router = useRouter(); const handleNavigate = () => { if (!detailPage) return; router.push(detailPage); // 用setTimeout确保路由跳转完成后执行滚动 setTimeout(() => { window.scrollTo(0, 0); }, 0); } return ( <div className={styles.card} onClick={handleNavigate}> {/* 组件原有内容 */} </div> ) } export default CapsuleCard;
问题原因
Next.js 13 App Router的默认滚动恢复逻辑,在服务器组件进行初始数据请求时,会因为异步渲染的时机问题,导致滚动位置没有被正确重置为顶部。手动触发滚动可以强制覆盖这一异常行为。
内容的提问来源于stack exchange,提问作者Orchi
相关产品推荐
相关产品推荐

