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

React项目中State结合Scrollspy使用时锚点href跳转失效问题求助

问题根因

  • 未清理scroll事件监听,组件重渲染时会重复注册监听,频繁触发setNavbar导致Header组件反复重渲染,打断锚点默认跳转行为
  • React Router会拦截原生<a>标签的跳转行为,单页应用内的锚点跳转无法触发默认滚动逻辑
  • 你引入的react-scrollspy仅负责滚动时匹配激活导航项,没有内置点击跳转锚点的能力

修复方案

第一步:修复scroll事件内存泄漏问题

把你代码中直接写在组件根作用域的window.addEventListener逻辑移到useEffect中,添加销毁清理逻辑,避免重复监听:

import { useState, useEffect } from "react"; // 确保引入useEffect

const Header = () => {
  const [click, setClick] = useState(false);
  const handleClick = () => setClick(!click);
  const [navbar, setNavbar] = useState(false);

  // 替换原来的changeBackground和addEventListener逻辑
  useEffect(() => {
    const changeBackground = () => {
      setNavbar(window.scrollY >= 80);
    };
    window.addEventListener("scroll", changeBackground);
    // 组件卸载时清理监听
    return () => window.removeEventListener("scroll", changeBackground);
  }, []);

  // 剩余原有逻辑...
}

第二步:自定义锚点跳转逻辑,替换原生a标签跳转

新增滚动到指定锚点的工具函数,阻止默认跳转行为,手动触发页面滚动:

const Header = () => {
  // 原有state和useEffect逻辑...

  // 新增锚点滚动函数,offset和scrollspy的offset配置保持一致
  const scrollToAnchor = (anchorId) => {
    const target = document.getElementById(anchorId);
    if (!target) return;
    window.scrollTo({
      top: target.offsetTop - 200,
      behavior: "smooth"
    });
  };

  return (
    <>
      <div className="cigi_topbar">
        <div className={navbar ? "topbar_inner opened" : "topbar_inner"}>
          <div className="logo">
            <NavLink to="/">
              <img src="/img/logo/new/smCTGearonly.png" alt="partners brand" />
            </NavLink>
          </div>
          <div className="menu">
            <Scrollspy
              className="anchor_nav"
              items={["home", "about", "portfolio", "skills", "contact"]}
              currentClassName="current"
              offset={-200}
            >
              <li>
                <a href="#home" onClick={(e) => {
                  e.preventDefault();
                  scrollToAnchor("home");
                }}>Home</a>
              </li>
              <li>
                <a href="#about" onClick={(e) => {
                  e.preventDefault();
                  scrollToAnchor("about");
                }}>About</a>
              </li>
              {/* 剩余portfolio、skills、contact导航项按上面的格式修改即可 */}
            </Scrollspy>
          </div>
        </div>
      </div>
    </>
  )
}

第三步:确认页面模块id匹配

检查页面中对应展示模块的id,确保和Scrollspy的items数组中配置的字符串完全一致,比如首页容器要设置id="home",关于模块要设置id="about",大小写无偏差。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 06:06:02