Next.js:点击返回按钮恢复原滚动位置且不影响其他页面滚动
在Next.js中实现返回时恢复页面滚动位置且不影响其他页面
可以实现。你当前方案的核心问题是使用了全局共享的ScrollContext存储滚动位置,所有页面共用同一个scrollPos值,导致其他页面滚动时会覆盖原页面的存储值,返回时自然无法得到正确的位置。
正确实现方案(按路由独立存储滚动位置)
我们需要为每个页面的路由单独存储滚动位置,避免状态互相干扰,推荐使用sessionStorage来实现:
1. 移除全局ScrollContext
删除你之前创建的ScrollContext相关代码,不再使用全局共享状态。
2. 在需要保留滚动的页面中添加逻辑
以Pages Router为例,在目标页面组件中添加以下代码:
import { useEffect } from 'react'; import { useRouter } from 'next/router'; export default function TargetPage() { const router = useRouter(); const scrollKey = `scrollPos_${router.pathname}`; useEffect(() => { // 页面挂载时恢复滚动位置 const savedPos = sessionStorage.getItem(scrollKey); if (savedPos) { window.scrollTo(0, parseInt(savedPos, 10)); } // 监听滚动事件,实时保存位置 const handleScroll = () => { sessionStorage.setItem(scrollKey, window.scrollY.toString()); }; window.addEventListener('scroll', handleScroll); // 页面卸载时最终保存一次位置 return () => { window.removeEventListener('scroll', handleScroll); sessionStorage.setItem(scrollKey, window.scrollY.toString()); }; }, [router.pathname, scrollKey]); // 页面内容 return ( <div> {/* 你的页面元素 */} </div> ); }
3. 调整Link组件配置
不需要全局设置scroll={false},保持Link组件的默认scroll={true}行为:
<SiteLink href={slug} />
这样跳转到新页面时会自动滚动到顶部,新页面的滚动位置会存在自己的路由key下,不会影响原页面的存储值。
关于Next.js原生scrollRestoration的说明
如果你使用的是Pages Router,experimental.scrollRestoration: true配置可以让Next.js自动处理浏览器前进后退的滚动恢复,但自定义存储方案更灵活,能完全避免页面间的状态干扰,适合复杂场景。
内容的提问来源于stack exchange,提问作者haris khan
相关产品推荐
相关产品推荐

