如何复用含state与eventListener的React滚动监听setFixed函数?
复用滚动固定状态逻辑的解决方案
要复用这种滚动控制固定状态的逻辑,最适合的方式是封装成自定义React Hook,这样任何组件都可以独立调用,且各自维护自己的状态,同时还能避免原代码中的内存泄漏问题。
步骤1:封装自定义Hook useScrollFixed
把状态管理、滚动监听和清理逻辑抽离到单独的Hook中:
import { useState, useEffect } from 'react'; function useScrollFixed(threshold = 0) { const [isFixed, setIsFixed] = useState(false); const handleScroll = () => { setIsFixed(window.scrollY > threshold); }; useEffect(() => { // 添加滚动监听 window.addEventListener('scroll', handleScroll); // 组件卸载时移除监听,避免内存泄漏 return () => { window.removeEventListener('scroll', handleScroll); }; }, [threshold]); // 阈值变化时重新绑定监听 return isFixed; }
这个Hook接受可选的滚动阈值参数(默认0),返回当前是否需要固定的状态,同时自动处理监听的添加和清理。
步骤2:在原NavBar组件中使用Hook
修改原组件,替换掉内部的状态和监听逻辑:
const NavBar = () => { const isFixed = useScrollFixed(); // 使用自定义Hook return ( <div className={isFixed ? `${styles.navbar} ${styles.sticky}` : styles.navbar}> <div className={styles["nav-wrapper"]}> <div className={styles["img-wrapper"]}> <img className={styles.logo} src={Logo} alt="网站Logo" /> </div> <ul className={styles["navbar-links"]}> <li className={styles["navbar-links__item"]}> <a>Home</a> </li> <li className={styles["navbar-links__item"]}> <a>About</a> </li> <li className={styles["navbar-links__item"]}> <a>Contact</a> </li> </ul> </div> </div> ); }; export default NavBar;
步骤3:在其他组件中复用
比如在侧边栏组件中使用,还可以自定义滚动阈值:
const Sidebar = () => { // 设置滚动超过100px时触发固定状态 const isFixed = useScrollFixed(100); return ( <div className={isFixed ? `${styles.sidebar} ${styles.fixed}` : styles.sidebar}> {/* 侧边栏内容 */} </div> ); };
关键优势
- 逻辑复用:无需重复编写滚动监听和状态判断代码
- 独立状态:每个组件调用Hook时都会拥有自己的
isFixed状态,互不干扰 - 内存安全:通过
useEffect的清理函数自动移除监听,避免组件卸载后触发无效状态更新
内容的提问来源于stack exchange,提问作者user19144150
相关产品推荐
相关产品推荐

