React TypeScript中scrollY状态不更新(elContainer为null)的修复咨询
问题修复方案
问题根源
- 你在组件顶层提前解构了
refContainer.current为elContainer,此时组件初始化阶段DOM还未挂载,elContainer的值为null,且该变量不会随ref的更新自动同步。 useCallback的依赖数组为空,导致handleScroll函数捕获的elContainer始终是初始的null,即便后续ref绑定了DOM元素,函数内的elContainer也不会更新。- 额外问题:你绑定的是
document的滚动事件,但实际滚动容器是自定义的div(带有overflow-scroll类),这会导致只有页面整体滚动时才触发事件,容器内部滚动不会触发。
修复后的代码
export const HomePage = (): JSX.Element => { const refContainer = useRef<HTMLDivElement>(null); const [scrollY, setScrollY] = useState<number>(0); const handleScroll = useCallback(() => { // 直接访问ref的current,每次调用都取最新DOM引用 if (refContainer.current) { setScrollY(refContainer.current.scrollTop); } }, []); // useRef返回的ref对象是稳定引用,无需加入依赖 useEffect(() => { const targetEl = refContainer.current; if (!targetEl) return; // DOM未挂载时直接返回 // 监听滚动容器自身的scroll事件,而非document targetEl.addEventListener("scroll", handleScroll, { passive: true }); return () => { targetEl.removeEventListener("scroll", handleScroll); }; }, [handleScroll]); return ( <div className="pageScreen overflow-scroll" ref={refContainer}> <Works scrollY={scrollY} /> </div> ); };
关键修复点
- 移除顶层的
elContainer解构,直接在handleScroll中访问refContainer.current,确保每次触发事件时都能获取最新的DOM元素。 - 将滚动事件绑定到目标容器(
refContainer.current),而非document,保证容器内部滚动时能正确触发事件。 - 在
useEffect中先判断DOM是否挂载,避免无效的事件绑定。
内容的提问来源于stack exchange,提问作者iufb
相关产品推荐
相关产品推荐

