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

Next.js点击浏览器后退按钮返回列表页自动滚动到顶部如何解决

问题根因

这个自动回到顶部的行为是Next.js的默认路由行为,和React无关。Next.js默认会在每次路由跳转完成后自动将页面滚动位置重置到顶部,你的自定义滚动设置逻辑执行时机和默认逻辑冲突,就会被覆盖。

修复方案

方案1:启用Next.js原生滚动恢复(最省心)

Next.js官方已经提供了滚动恢复的内置支持,不需要自己写context存储滚动位置:

  • 如果你用的是Next.js 13+ App Router,直接在next.config.js中添加如下配置即可:
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    scrollRestoration: true,
  },
}

module.exports = nextConfig
  • 如果你用的是Pages Router,在_app.js中关闭全局自动滚动即可:
function MyApp({ Component, pageProps, router }) {
  return <Component {...pageProps} scroll={false} />
}

方案2:调整自定义逻辑的执行时机

如果你要保留自己用context存滚动位置的逻辑,需要修改两个点:

  1. 避开Next.js默认滚动重置的时机,不要在组件初始useEffect里设置滚动,改成监听路由完成事件后执行:
import { useRouter } from 'next/router'
import { useEffect } from 'react'
// 假设你从context中拿到的存储滚动值为savedScrollY
const ListComponent = () => {
  const router = useRouter()

  useEffect(() => {
    const restoreScroll = () => {
      // 确认当前回到列表页后再设置滚动
      if (router.pathname === '/list') {
        window.scrollTo(0, savedScrollY)
      }
    }
    // 路由完全跳转完成后再恢复滚动
    router.events.on('routeChangeComplete', restoreScroll)
    return () => router.events.off('routeChangeComplete', restoreScroll)
  }, [router, savedScrollY])

  // 组件其余逻辑
}
  1. 优化你的window滚动监听逻辑:在主动调用scrollTo恢复滚动的100ms内暂时屏蔽监听器的更新,避免主动设置滚动的动作被监听器捕获,误将存储的滚动值覆盖为0。

特殊情况处理

如果你的滚动容器是list组件内部的可滚动区域(不是全局window滚动),需要额外注意:

  • 不要用window.scrollTo,要拿到滚动容器的DOM引用,设置containerRef.current.scrollTop = savedScrollY
  • 必须等列表的所有产品数据渲染完成、容器高度稳定后再设置滚动位置,否则会因为内容高度不足导致滚动设置失效。

内容的提问来源于stack exchange,提问作者Henry Peregrino

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:51:00