You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 22:42:24