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

React TypeScript中scrollY状态不更新(elContainer为null)的修复咨询

问题修复方案

问题根源

  1. 你在组件顶层提前解构了refContainer.current为elContainer,此时组件初始化阶段DOM还未挂载,elContainer的值为null,且该变量不会随ref的更新自动同步。
  2. useCallback的依赖数组为空,导致handleScroll函数捕获的elContainer始终是初始的null,即便后续ref绑定了DOM元素,函数内的elContainer也不会更新。
  3. 额外问题:你绑定的是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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 07:37:13