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

如何在Next.js路由场景下正确使用Locomotive Scroll 解决滚动实例重叠问题

问题原因分析
  • 你当前的scroll实例是useEffect内部的局部变量,路由跳转后无法拿到上一次渲染生成的旧实例,导致旧实例始终没有被真正销毁,每次渲染都新建实例自然会出现重叠
  • useEffect没有传入依赖数组,每次组件渲染都会重复执行导入和初始化逻辑,进一步加剧实例重复问题
  • 刚new完实例就立刻调用destroy再延时init的逻辑是错误的,你销毁的是刚创建的新实例,而不是上一个路由的旧实例
正确实现方案

以下是Pages路由下_app.js的修正代码:

import { useEffect, useRef } from 'react'
import { useRouter } from 'next/router'

function MyApp({ Component, pageProps }) {
  // 存储滚动实例,跨渲染/路由变化可访问
  const scrollRef = useRef(null)
  // 存储定时器ID,避免多个定时器叠加
  const initTimeoutRef = useRef(null)
  const router = useRouter()

  // 滚动实例初始化通用方法
  const initScroll = async () => {
    // 初始化前先销毁已有旧实例
    if (scrollRef.current) {
      scrollRef.current.destroy()
      scrollRef.current = null
    }
    // 动态导入locomotive-scroll
    const locomotiveModule = await import("locomotive-scroll")
    // 清理上一个未执行的定时器
    if (initTimeoutRef.current) clearTimeout(initTimeoutRef.current)
    // 等待新页面DOM完全渲染后再初始化
    initTimeoutRef.current = setTimeout(() => {
      const scrollContainer = document.querySelector("[data-scroll-container]")
      if (!scrollContainer) return
      scrollRef.current = new locomotiveModule.default({
        el: scrollContainer,
        smooth: true,
        smoothMobile: false,
        resetNativeScroll: true,
      })
    }, 300)
  }

  useEffect(() => {
    // 首次进入页面初始化实例
    initScroll()

    // 监听路由跳转完成事件,每次跳转后重新初始化
    const handleRouteChange = () => initScroll()
    router.events.on('routeChangeComplete', handleRouteChange)

    // 页面卸载/关闭时清理所有资源
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange)
      if (initTimeoutRef.current) clearTimeout(initTimeoutRef.current)
      if (scrollRef.current) {
        scrollRef.current.destroy()
        scrollRef.current = null
      }
    }
  }, [])

  return (
    <main data-scroll-container>
      <Component {...pageProps} />
    </main>
  )
}

export default MyApp

如果你使用的是Next.js 13+ App Router,只需要把路由监听逻辑换成监听usePathname返回的路径变化,核心逻辑完全一致。

内容的提问来源于stack exchange,提问作者Denis Kunitsyn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 06:27:01