前端 React实现数据懒加载和滚动触底加载数据的过程

 更新时间:2025年08月23日 09:59:37   作者:新时代农民工Top  
本文给大家介绍前端React实现数据懒加载和滚动触底加载数据的过程,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

什么是React的懒加载(Lazy Loading),如何实现?

在现代前端开发中,性能是一个至关重要的指标。随着应用程序日益增长和复杂,如何有效地管理资源和优化加载时间成为了每位开发者必须面对的挑战。为此,React 提供了懒加载(Lazy Loading)这一强大功能,帮助开发者按需加载组件,提高应用架构的灵活性和性能。

懒加载的概念
懒加载是一种设计模式,只有在需要的时候才加载某个资源或组件,而不是在应用启动时一次性加载所有资源。在 React 中,懒加载通常用于组件的按需加载。通过懒加载,用户可以避免在早期阶段加载不必要的组件,实现流畅的用户体验,同时减少初始下载的大小。

为什么要使用懒加载

  • 提升性能:通过只加载用户需要的部分,减少了初始加载时间和数据传输的大小,从而提升应用的性能。
  • 优化用户体验:提高页面响应速度,使用户能更快地查看和使用应用的核心功能。
  • 代码分割:懒加载有助于实现代码分割,将大文件拆分成多个小块,用户只有在交互需要时才会请求相应的代码。

在 React 中使用 Intersection Observer API 实现触底加载分页(无限滚动)

1.基本实现思路

  • 在列表底部放置一个 哨兵元素(Sentinel)(如 <div>)。
  • 使用 IntersectionObserver 监听该元素是否进入视口(即触底)。
  • 触底时加载下一页数据,并更新列表。

2.完整代码实例

import { useState, useEffect, useRef } from 'react';
function InfiniteScrollList() {
  const [data, setData] = useState([]); // 当前数据
  const [page, setPage] = useState(1);  // 当前页码
  const [loading, setLoading] = useState(false); // 加载状态
  const [hasMore, setHasMore] = useState(true);  // 是否还有更多数据
  const sentinelRef = useRef(null); // 哨兵元素的 ref
  // 模拟异步加载数据
  const fetchData = async () => {
    if (loading || !hasMore) return;
    setLoading(true);
    // 模拟 API 请求(替换为实际接口)
    const mockData = Array.from({ length: 10 }, (_, i) => 
      `Item ${(page - 1) * 10 + i + 1}`
    );
    // 模拟延迟
    await new Promise(resolve => setTimeout(resolve, 1000));
    setData(prev => [...prev, ...mockData]);
    setPage(prev => prev + 1);
    setLoading(false);
    // 假设第 5 页后无数据
    if (page >= 5) setHasMore(false);
  };
  // 初始化 IntersectionObserver
  useEffect(() => {
    if (!sentinelRef.current || !hasMore) return;
    const observer = new IntersectionObserver(
      (entries) => {
        const [entry] = entries;
        if (entry.isIntersecting) {
          fetchData(); // 触底时加载数据
        }
      },
      { threshold: 1.0 } // 当哨兵元素完全进入视口时触发
    );
    observer.observe(sentinelRef.current);
    return () => {
      if (sentinelRef.current) observer.unobserve(sentinelRef.current);
    };
  }, [page, hasMore, loading]); // 依赖项
  return (
    <div style={{ maxHeight: '400px', overflow: 'auto' }}>
      <h2>无限滚动列表</h2>
      <ul>
        {data.map((item, index) => (
          <li key={index} style={{ padding: '10px', borderBottom: '1px solid #eee' }}>
            {item}
          </li>
        ))}
      </ul>
      {/* 哨兵元素:用于检测触底 */}
      <div ref={sentinelRef} style={{ height: '20px' }}>
        {loading && <p>加载中...</p>}
        {!hasMore && <p>没有更多数据了</p>}
      </div>
    </div>
  );
}
export default InfiniteScrollList;

3.关键点说明

  • 哨兵元素(Sentinel)
    • 一个隐藏的 <div> 作为触底标记,通过 ref 绑定到 IntersectionObserver
  • IntersectionObserver 配置
    • threshold: 1.0:当哨兵元素 100% 进入视口时触发回调。
    • useEffect 中初始化并清理观察器,避免内存泄漏。
  • 加载控制逻辑
    • loading 防止重复请求。
    • hasMore 标记数据是否全部加载完毕。
  • 性能优化
    • 使用 useCallback 包裹 fetchData(如果函数逻辑复杂)。
    • 实际项目中,结合分页接口的 total 字段判断是否还有数据。

4.实际项目适配

  • 替换 fetchData 中的模拟请求为真实 API 调用(如 axios 或 fetch)。
  • 可加入防抖(Debounce)优化频繁触发问题(如快速滚动时)。

简易封装触底自动加载数据组件 InfiniteScroll.jsx

import { useEffect, useRef } from 'react'
const InfiniteScroll = (props) => {
  // children 可以设置触底时显示的提示文字,加载状态等
  // loadMore 加载数据的接口方法
  // hasMore 检查数据是否全部加载完毕,分页加载之后还有下一页数据保持 true 不变,确保后续不会再有数据则为 false
  // rootElement 浏览器可视窗口或者自定义滚动视口
  const { children, loadMore, hasMore, rootElement = null } = props
  const sentinelRef = useRef(null)
  useEffect(() => {
    if (!sentinelRef.current || !hasMore) return;
    const observer = new window.IntersectionObserver(
      ([{isIntersecting}]) => {
        if (isIntersecting) {
          // 加载数据接口调用,当该组件进入浏览器视口时就会触发
          loadMore()
        }
      },
      { threshold: 1.0, root: rootElement }
    );
    observer.observe(sentinelRef.current);
    return () => {
      if (sentinelRef.current) observer.unobserve(sentinelRef.current);
    };
  }, [hasMore])
  return (
  	// 哨兵容器,目标元素,用来监听是否加载数据,目标元素与视口交叉 isIntersecting 值就会变化
    <div ref={sentinelRef} style={{ minHeight: '2px', textAlign: 'center' }}>
      {children}
    </div>
  )
}
export default InfiniteScroll

使用示例

const CustomComponent = () => {
  // 加载数据函数
  const loadMore = () => {
    // ...
  }
  return (
    <>
      // ...
      // 循环数据,将组件放置在循环数据的底部即可
      <InfiniteScroll loadMore={loadMore} hasMore={hasMore}>
        {hasMore && <Spin indicator={<LoadingOutlined spin />} size="large" />}
      </InfiniteScroll>
      // ...
    </>
  )
}

到此这篇关于前端 React实现数据懒加载和滚动触底加载数据的过程的文章就介绍到这了,更多相关React懒加载和滚动触底加载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于react项目打包css引用路径错误解决方案

    基于react项目打包css引用路径错误解决方案

    这篇文章主要介绍了基于react项目打包css引用路径错误解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • React Hooks项目实战

    React Hooks项目实战

    React Hooks是React 16.8版本引入的新特性,它使得在函数组件中也能够使用状态(state)和其他React特性,本文就来详细介绍一下React Hooks项目实战,感兴趣的可以了解一下
    2023-11-11
  • react-router-dom6(对比 router5)快速入门指南

    react-router-dom6(对比 router5)快速入门指南

    这篇文章主要介绍了快速上手react-router-dom6(对比 router5),通过本文学习最新的react-router-dom v6版本的路由知识,并且会与v5老版本进行一些对比,需要的朋友可以参考下
    2022-08-08
  • react-rnd靠右显示的实现方式

    react-rnd靠右显示的实现方式

    这篇文章主要介绍了react-rnd靠右显示的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-05-05
  • React 状态的不变性实例详解

    React 状态的不变性实例详解

    这篇文章主要为大家介绍了React 状态的不变性实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • react调试和测试代码的小技巧

    react调试和测试代码的小技巧

    在开发React应用时,严格模式StrictMode可以帮助开发者捕捉到组件中的错误和潜在问题,安装React Developer Tools浏览器扩展检查组件的props和状态,直接修改以及分析性能,@testing-library/react和Cypress或Playwright等工具可以有效地测试React组件和执行端到端测试
    2024-10-10
  • 深入理解React调度(Scheduler)原理

    深入理解React调度(Scheduler)原理

    本文主要介绍了深入理解React调度(Scheduler)原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • 浅谈react性能优化的方法

    浅谈react性能优化的方法

    这篇文章主要介绍了浅谈react性能优化的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • 如何去除富文本中的html标签及vue、react、微信小程序中的过滤器

    如何去除富文本中的html标签及vue、react、微信小程序中的过滤器

    这篇文章主要介绍了如何去除富文本中的html标签及vue、react、微信小程序中的过滤器,在vue及react中经常会遇到,今天通过实例代码给大家讲解,需要的朋友可以参考下
    2018-11-11
  • 快速创建React项目并配置webpack

    快速创建React项目并配置webpack

    这篇文章主要介绍了创建React项目并配置webpack,在这里需要注意,Create React App requires Node 14 or higher.需要安装高版本的node,本文给大家介绍的非常详细,需要的朋友参考下吧
    2022-01-01

最新评论