使用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
相关产品推荐
相关产品推荐

