如何在React中实现滚动触发的粘性导航栏效果
导航栏滚动粘性效果修复方案
现有代码问题点
stickNavbar函数内三元运算符逻辑颠倒,实际未按滚动高度判断是否添加粘性类- 滚动事件监听未在组件卸载时移除,会触发内存泄漏
- JSX中
div、nav标签闭合语法错误,会导致组件渲染异常 - 导航栏切换为fixed定位后脱离文档流,原本占位高度消失,会导致页面内容出现突兀跳动
修复后代码
Navbar.js
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
相关产品推荐
相关产品推荐

