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
相关产品推荐
相关产品推荐

