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

react-scroll的Link点击后滚动延迟1.5秒,如何修复?

React Scroll点击滚动延迟问题解决

我在React导航栏中使用react-scroll的Link组件,点击后本该自动滚动到页面指定位置,但实际有大约1.5秒的延迟,求解决办法。

我的Navbar.js代码

import React from "react";
import { Link } from 'react-scroll';
import { FaBars, FaTimes } from 'react-icons/fa';
import { useState, useEffect } from "react";
import '../styles/Navbar.css';


const Navbar = () => {

  const [click, setClick] = useState(false);
  const handleClick = () => setClick(!click);
  const closeMenu = () => setClick(false);
  const [fix, setFix] = useState(false);

  const setFixed = () => {
    if (window.scrollY >= 950) {
      setFix(true);
    } else {
      setFix(false);
    };
  };

  window.addEventListener("scroll", setFixed);
  return (
      <div className={fix ? 'header active' : 'header'}>
          <nav className={fix ? 'navbar fixed' : 'navbar'}>
              <div className='hamburger' onClick={handleClick}>
                  {click ? (<FaTimes size={30} style={{ color: '#ffffff' }} />)
                      : (<FaBars size={30} style={{ color: '#ffffff' }} />)}
              </div>
              <ul className={click ? "nav-menu active" : "nav-menu"}>
                  <li className='nav-item'>
                    <Link to="header" spy={true} smooth={true} offset={-100} onClick={closeMenu} id="homeLink">Home</Link>
                  </li>
                  <li className='nav-item'>
                    <Link to="aboutMe" spy={true} smooth={true} offset={-100} onClick={closeMenu}>About</Link>
                  </li>
                  <li className='nav-item'>
                    <Link to="/" spy={true} smooth={true} offset={50} onClick={closeMenu}>Resume</Link>
                  </li>
                  <li className='nav-item'>
                    <Link to="/" spy={true} smooth={true} offset={50} onClick={closeMenu}>Projects</Link>
                  </li>
              </ul>
          </nav>
      </div>
  )
}

export default Navbar;

我的Navbar.css代码

.header {
  position: fixed;
  height: 90px;
  width: 100%;
  top: 0;
  left: 0;
  z-index: 1;
  transition: .3s ease-in;
  overflow: hidden;
  background-color: transparent;
}

.header.active {
  background-color: rgba(0,0,0,.9);
}

.header .navbar {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: auto;
  height: 100%;
  padding: 0 1rem;
}

.header .nav-menu a {
  color: #ffffff;
}

.header .nav-menu {
  display: flex;
}

.header .nav-item {
  padding: 1rem;
  font-weight: 500;
}

.header .nav-item a:hover {
  padding-bottom: 4px;
  color: #ffea00;
  border-bottom: 3px solid #ffea00;
}

.hamburger {
  display: none;
}

.nav-item {
  list-style: none;
}

#homeLink {
  text-decoration: none;
}

@media screen and (max-width:940px) {
  .header {
      max-width: 100%;
      background-color: rgba(0,0,0,.9);
  }

  .header .navbar {
      max-width: 100%;
      justify-content: space-between;
  }

  .hamburger {
      display: block;
  }

  .nav-menu {
      position: fixed;
      left: -100%;
      top: 90px;
      flex-direction: column;
      background-color: rgba(0,0,0,.9);
      width: 100%;
      height: 90vh;
      z-index: 999;
      text-align: center;
      transition: .3s;
  }

  .nav-menu.active {
      left: 0;
  }

  .nav-item {
      margin: 1.5rem 0;
  }

  .header .navbar img {
      width: 150px;
  }
}

问题排查与修复方案

1. 修复scroll事件监听的重复绑定与内存泄漏

你的代码直接在组件顶层执行window.addEventListener("scroll", setFixed);,会导致每次组件渲染都新增一个scroll监听,监听越积越多,触发大量不必要的setState,引发组件重复渲染,拖慢页面响应速度。

修改方式:用useEffect包裹监听逻辑,并在组件卸载时清理监听:

useEffect(() => {
  const setFixed = () => {
    setFix(window.scrollY >= 950);
  };
  window.addEventListener("scroll", setFixed);
  // 组件卸载时移除监听
  return () => window.removeEventListener("scroll", setFixed);
}, []);

2. 修正react-scroll的Link目标路径

Resume和Projects的Link组件to属性写的是"/",这是路由路径,但react-scroll的to需要对应页面中目标元素的id(比如<div id="resume">...</div>),而非路由地址。错误的目标会导致scroll逻辑找不到元素,出现延迟或无响应。

修改示例:

<li className='nav-item'>
  <Link to="resume" spy={true} smooth={true} offset={50} onClick={closeMenu}>Resume</Link>
</li>
<li className='nav-item'>
  <Link to="projects" spy={true} smooth={true} offset={50} onClick={closeMenu}>Projects</Link>
</li>

确保页面中存在对应id的元素:<section id="resume">...</section>、<section id="projects">...</section>

3. 优化scroll事件的防抖处理

scroll事件触发频率极高,即使修复了监听绑定,频繁的setState仍可能导致页面卡顿。给setFixed添加防抖,减少setState的触发次数:

import { useEffect, useState } from "react";
// 防抖函数
const debounce = (func, delay) => {
  let timeoutId;
  return (...args) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
};

const Navbar = () => {
  // ...其他状态
  useEffect(() => {
    const debouncedSetFixed = debounce(() => {
      setFix(window.scrollY >= 950);
    }, 100); // 100ms防抖间隔,可根据需求调整
    window.addEventListener("scroll", debouncedSetFixed);
    return () => window.removeEventListener("scroll", debouncedSetFixed);
  }, []);
  // ...其余代码
}

4. 调整closeMenu的执行时机

closeMenu同步修改click状态,可能和react-scroll的滚动逻辑存在微小冲突。尝试把closeMenu改成延迟执行:

const closeMenu = () => {
  setTimeout(() => setClick(false), 50);
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 06:35:30