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

使用react-intersection-observer懒加载时如何避免组件频繁重挂载?

解决React-intersection-observer懒加载组件滚出视口卸载后重挂载导致的滚动跳转问题

问题分析

当前实现的核心问题在于:LazyComponent仅在目标组件处于视口内(inView为true)时渲染它,一旦组件滚出视口,inView变为false,目标组件就会被卸载。当再次滚动回视口时,组件重新挂载,由于目标组件高度较大,浏览器会自动调整滚动位置到新挂载元素的顶部,引发页面跳转。

解决方案

核心思路是让目标组件在首次加载后保持挂载状态,不再因滚出视口而卸载。通过添加状态变量记录组件是否已加载,结合inView触发首次加载逻辑即可解决问题。

修改后的完整代码

import React, { useState, useEffect } from "react";
import { useInView } from "react-intersection-observer";

const LazyComponent = ({ LoadableComponent, ...rest }) => {
  const { ref, inView } = useInView({ rootMargin: "50px 0px" });
  // 记录组件是否已完成首次加载
  const [isLoaded, setIsLoaded] = useState(false);

  // 当组件首次进入视口时,标记为已加载(仅触发一次)
  useEffect(() => {
    if (inView) {
      setIsLoaded(true);
    }
  }, [inView]);

  // 一旦加载完成,始终保持组件挂载状态
  return (
    <div ref={ref}>
      {isLoaded && <LoadableComponent {...rest} />}
    </div>
  );
};

const MyComponent = (props) => {
  return (
    <div style={{ height: "4000px", backgroundColor: "blue" }}>
      <p>This is the top of MyComponent.</p>
    </div>
  );
};

export default function App() {
  return (
    <div className="App">
      <h1>Title</h1>
      <div style={{ height: "1000px", backgroundColor: "green" }}></div>
      <LazyComponent LoadableComponent={MyComponent} />
      <div style={{ height: "1000px", backgroundColor: "red" }}></div>
    </div>
  );
}

关键逻辑说明

  • 新增isLoaded状态变量,专门用于记录目标组件是否已完成首次加载。
  • 通过useEffect监听inView的变化,仅在组件首次进入视口时将isLoaded设为true,确保加载逻辑只触发一次。
  • 渲染逻辑改为仅依赖isLoaded,一旦组件加载完成,无论是否在视口内,都保持挂载状态,彻底避免了卸载后重挂载导致的滚动跳转。

可选优化方案(隐藏而非卸载)

如果需要在组件滚出视口时隐藏但保留DOM结构(避免重复初始化开销),可以调整渲染逻辑为:

return (
  <div 
    ref={ref} 
    style={{ 
      visibility: isLoaded ? "visible" : "hidden",
      height: isLoaded ? "auto" : "0",
      overflow: "hidden"
    }}
  >
    <LoadableComponent {...rest} />
  </div>
);

这种方式下,组件始终存在于DOM中,仅通过CSS控制可见性和高度,同样可以避免滚动跳转,适合不需要完全卸载的场景。

内容的提问来源于stack exchange,提问作者Ruben Lemiengre

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 19:55:09