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

使用React Hooks实现滚动位置监听时无输出值恒为0问题求解

问题原因

  • useEffect依赖配置错误:你将scrollPosition加入了useEffect的依赖数组,每次scrollPosition更新时,都会先执行useEffect的清理函数移除滚动监听器,再重新注册监听器,容易出现事件监听异常。实际上handleScroll不需要依赖外部的state变量,该依赖完全多余。
  • 滚动容器不是全局window:如果你的页面滚动是通过内部容器设置overflow: auto/scroll实现的,全局window本身没有产生滚动,window.scrollY自然永远是0,也不会触发window的scroll事件。

修复方案

情况1:确实是全局window滚动

直接把useEffect的依赖数组改成空数组,保证只在组件挂载时注册一次监听、卸载时清理一次即可:

const [scrollPosition, setScrollPosition] = useState(0);
const handleScroll = () => {
    const position = window.scrollY;
    console.log(position);
    setScrollPosition(position);
};

useEffect(() => {
    window.addEventListener('scroll', handleScroll, { passive: true });
    return () => {
        window.removeEventListener('scroll', handleScroll);
    };
}, []);

情况2:滚动的是组件内的容器元素

给滚动容器绑定ref,监听容器自身的scroll事件,读取scrollTop属性获取滚动位置:

const [scrollPosition, setScrollPosition] = useState(0);
const scrollRef = useRef(null);

const handleScroll = () => {
    const position = scrollRef.current.scrollTop;
    console.log(position);
    setScrollPosition(position);
};

useEffect(() => {
    const scrollEl = scrollRef.current;
    scrollEl.addEventListener('scroll', handleScroll, { passive: true });
    return () => {
        scrollEl.removeEventListener('scroll', handleScroll);
    };
}, []);

// 渲染时给滚动容器绑定ref
return <div ref={scrollRef} style={{overflow: 'auto', height: '100vh'}}>
    {/* 页面内容 */}
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 02:36:08