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

如何在React中实现滚动触发的粘性导航栏效果

导航栏滚动粘性效果修复方案

现有代码问题点

  • stickNavbar函数内三元运算符逻辑颠倒,实际未按滚动高度判断是否添加粘性类
  • 滚动事件监听未在组件卸载时移除,会触发内存泄漏
  • JSX中div、nav标签闭合语法错误,会导致组件渲染异常
  • 导航栏切换为fixed定位后脱离文档流,原本占位高度消失,会导致页面内容出现突兀跳动

修复后代码

import { useEffect, useState } from "react";

const NavBar = () => {
  const [isSticky, setIsSticky] = useState(false);

  const stickNavbar = () => {
    setIsSticky(window.scrollY > 500);
  };

  useEffect(() => {
    window.addEventListener("scroll", stickNavbar);
    // 组件卸载清除事件监听
    return () => window.removeEventListener("scroll", stickNavbar);
  }, []);

  return (
    {/* 外层设置和导航栏等高的最小高度,避免页面跳动,数值可根据实际导航高度调整 */}
    <nav className="relative w-full p-4 min-h-[70px]">
      <div className={`flex w-full flex-row items-center justify-between ${isSticky ? 'sticky-nav' : ''}`}>
        navbar content goes here ....
      </div>
    </nav>
  );
};

export default NavBar;

可选优化:移除自定义CSS依赖

你可以直接在JSX内使用Tailwind内置类,无需额外维护components.css中的自定义类,将上述代码中的类名判断替换为以下内容即可:

${isSticky ? 'fixed top-0 left-0 w-full shadow-md z-20' : ''}

性能优化:添加滚动防抖

滚动事件触发频率极高,可添加防抖逻辑降低执行频率,避免不必要的状态更新:

import { useEffect, useState, useCallback } from "react";

// 防抖工具函数
const debounce = (func, delay = 200) => {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => func(...args), delay);
  };
};

const NavBar = () => {
  const [isSticky, setIsSticky] = useState(false);

  const stickNavbar = useCallback(debounce(() => {
    setIsSticky(window.scrollY > 500);
  }), []);

  useEffect(() => {
    window.addEventListener("scroll", stickNavbar);
    return () => window.removeEventListener("scroll", stickNavbar);
  }, [stickNavbar]);

  // 其余渲染逻辑和上文一致
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 16:06:07