当前位置:首页 > React

react实现触底加载

2026-01-26 22:11:36React

实现触底加载的基本思路

触底加载(Infinite Scroll)的核心逻辑是监听滚动事件,当页面滚动到接近底部时触发数据加载。React中可以通过结合useEffect和DOM事件监听实现。

监听滚动事件

在React组件中,通过useEffect添加滚动事件监听器,计算是否触达容器底部:

react实现触底加载

useEffect(() => {
  const handleScroll = () => {
    const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
    if (scrollTop + clientHeight >= scrollHeight - 10) {
      // 触发加载更多数据
    }
  };

  window.addEventListener('scroll', handleScroll);
  return () => window.removeEventListener('scroll', handleScroll);
}, []);

使用Intersection Observer API(推荐)

更现代的方式是使用Intersection Observer API,性能更好且不依赖频繁的滚动计算:

react实现触底加载

useEffect(() => {
  const observer = new IntersectionObserver(
    (entries) => {
      if (entries[0].isIntersecting) {
        // 触发加载更多数据
      }
    },
    { threshold: 1.0 }
  );

  const sentinel = document.querySelector('#load-more-sentinel');
  if (sentinel) observer.observe(sentinel);

  return () => observer.disconnect();
}, []);

完整组件示例

import { useState, useEffect } from 'react';

function InfiniteScrollList() {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(false);
  const [page, setPage] = useState(1);

  const fetchData = async () => {
    setLoading(true);
    // 模拟API请求
    const newItems = await fetch(`/api/items?page=${page}`);
    setItems(prev => [...prev, ...newItems]);
    setPage(prev => prev + 1);
    setLoading(false);
  };

  useEffect(() => {
    const observer = new IntersectionObserver(
      ([entry]) => entry.isIntersecting && !loading && fetchData(),
      { threshold: 1.0 }
    );
    observer.observe(document.querySelector('#sentinel'));
    return () => observer.disconnect();
  }, [loading]);

  return (
    <div>
      {items.map(item => (
        <div key={item.id}>{item.content}</div>
      ))}
      <div id="sentinel" style={{ height: '20px' }} />
      {loading && <div>Loading...</div>}
    </div>
  );
}

性能优化建议

  • 添加防抖逻辑避免频繁触发
  • 在卸载组件时清除事件监听
  • 使用useCallback缓存获取数据的函数
  • 添加错误处理机制
  • 考虑使用React Query等库管理数据状态

第三方库方案

现有成熟库可以快速实现该功能:

npm install react-infinite-scroll-component

使用示例:

import InfiniteScroll from 'react-infinite-scroll-component';

function List() {
  return (
    <InfiniteScroll
      dataLength={items.length}
      next={fetchData}
      hasMore={true}
      loader={<h4>Loading...</h4>}
    >
      {items.map(item => (
        <div key={item.id}>{item.text}</div>
      ))}
    </InfiniteScroll>
  );
}

标签: 加载触底
分享给朋友:

相关文章

js实现图片的懒加载

js实现图片的懒加载

实现图片懒加载的基本原理 懒加载的核心思想是延迟加载非视口内的图片,当用户滚动页面时再动态加载即将进入视口的图片资源。这能显著减少页面初始加载时的网络请求和带宽消耗。 Intersection Ob…

vue实现延迟加载

vue实现延迟加载

Vue 实现延迟加载的方法 使用动态导入(Dynamic Import)和异步组件 在 Vue 中,可以通过动态导入语法结合异步组件实现延迟加载。这种方式会在需要时才加载组件,而不是在初始加载时一并加…

vue实现加载更多

vue实现加载更多

Vue 实现加载更多功能 在 Vue 中实现加载更多功能通常涉及监听滚动事件或点击按钮触发加载更多数据。以下是几种常见的实现方式: 滚动监听实现无限滚动 通过监听滚动事件,当用户滚动到页面底部时自动…

vue懒加载实现方案

vue懒加载实现方案

vue懒加载实现方案 路由懒加载 使用动态导入语法实现路由级别的懒加载,适用于Vue Router配置。通过import()函数返回Promise,Webpack会自动分割代码块。 const ro…

vue表格实现加载更多

vue表格实现加载更多

实现 Vue 表格加载更多的几种方法 滚动加载(无限滚动) 通过监听滚动事件,当滚动到底部时加载更多数据。适用于长列表或表格。 <template> <div class="t…

Vue异步加载实现方法

Vue异步加载实现方法

异步组件的基本实现 使用Vue的defineAsyncComponent方法定义异步组件,适用于Vue 3.x版本。该方法接收一个返回Promise的加载函数: import { defineAsy…