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

ReactJS如何通过onScroll方法实现页面滚动时修改组件状态

问题根源

原有代码不生效核心原因如下:

  • 你将onScroll事件绑定在了普通div元素上,该元素没有设置固定高度与滚动溢出属性,自身不会产生滚动事件,回调永远不会触发
  • 页面级的滚动事件是挂载在window对象上的,无法通过普通元素的onScroll属性直接捕获
  • 缺少事件监听的清理逻辑,组件卸载后残留监听会引发内存泄漏
可用实现方案

通过useEffect在组件挂载时绑定window的全局滚动监听,组件卸载时自动移除监听,替换原有Header组件代码即可:

import { useState, useEffect } from 'react';

const Header = () => {
    const [background, setBackground] = useState(false);

    // 滚动事件处理逻辑
    const handleScroll = () => {
        // 若需要滚动后永久保留背景,直接写 setBackground(true) 即可
        // 下面写法支持滚动回顶部时恢复无背景状态,体验更好
        setBackground(window.scrollY > 0);
    };

    useEffect(() => {
        // 绑定全局滚动监听
        window.addEventListener('scroll', handleScroll);
        // 组件卸载时移除监听,避免内存泄漏
        return () => window.removeEventListener('scroll', handleScroll);
    }, []);

    return (
        <div>
            <div>
                {/* 提示:如果需要导航固定在顶部始终可见,给className追加 fixed top-0 left-0 z-50 即可 */}
                <div className={background ?
                 'nav bg-error w-[90%] py-5 mx-auto text-[white] flex justify-between ' 
                :
                 'nav w-[90%]  py-5 mx-auto text-[white] flex justify-between'}>
                    <div>
                        <p> logo</p>
                    </div>
                    <div>
                        <ul className='flex justify-around'>
                            <li>item1</li>
                            <li className='mx-10'>item2</li>
                            <li className='mr-10'>item3</li>
                            <li>item4</li>
                        </ul>
                    </div>
                </div>
            </div>
            <div className=' text-[white]'>
                <img src="https://img.freepik.com/free-photo/close-up-islamic-new-year-concept_23-2148611670.jpg?w=1380&t=st=1655822165~exp=1655822765~hmac=c5954765a3375adc1b56f2896de7ea8a604cd1fb725e53770c7ecd8a05821a60" alt="banner" />
            </div>
        </div>
    );
};

export default Header;
可选优化

如果页面滚动场景复杂,可以给handleScroll增加节流逻辑,控制事件触发频率在每16ms一次(匹配普通屏幕刷新率),避免频繁触发状态更新造成性能损耗。

内容的提问来源于stack exchange,提问作者Md Joynul Abedin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 18:45:32