当前位置:首页 > React

react实现滚动分页

2026-01-26 22:13:12React

实现滚动分页的基本思路

滚动分页(Infinite Scroll)的核心是通过监听滚动事件,在用户接近页面底部时自动加载更多数据。React中通常结合Intersection Observer API或手动计算滚动位置实现。

使用Intersection Observer API

Intersection Observer是现代浏览器提供的API,性能优于手动监听滚动事件。

import { useState, useEffect, useRef } from 'react';

function InfiniteScrollList() {
  const [items, setItems] = useState([]);
  const [page, setPage] = useState(1);
  const loaderRef = useRef(null);

  useEffect(() => {
    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0].isIntersecting) {
          loadMoreItems();
        }
      },
      { threshold: 1.0 }
    );

    if (loaderRef.current) {
      observer.observe(loaderRef.current);
    }

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

  const loadMoreItems = async () => {
    const newItems = await fetchItems(page);
    setItems(prev => [...prev, ...newItems]);
    setPage(prev => prev + 1);
  };

  return (
    <div>
      {items.map(item => (
        <div key={item.id}>{item.content}</div>
      ))}
      <div ref={loaderRef}>Loading more items...</div>
    </div>
  );
}

手动监听滚动事件

兼容性更好的传统方法,需注意防抖(debounce)优化:

import { useState, useEffect } from 'react';

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

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

  const handleScroll = () => {
    if (
      window.innerHeight + document.documentElement.scrollTop !==
        document.documentElement.offsetHeight ||
      loading
    ) {
      return;
    }
    loadMoreItems();
  };

  const loadMoreItems = async () => {
    setLoading(true);
    const newItems = await fetchItems(page);
    setItems(prev => [...prev, ...newItems]);
    setPage(prev => prev + 1);
    setLoading(false);
  };

  return (
    <div>
      {items.map(item => (
        <div key={item.id}>{item.content}</div>
      ))}
      {loading && <div>Loading...</div>}
    </div>
  );
}

使用现成库简化实现

第三方库如react-infinite-scroll-component可快速实现:

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

function InfiniteScrollList() {
  const [items, setItems] = useState([]);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(true);

  const fetchMoreData = async () => {
    const newItems = await fetchItems(page);
    if (newItems.length === 0) setHasMore(false);
    setItems(prev => [...prev, ...newItems]);
    setPage(prev => prev + 1);
  };

  return (
    <InfiniteScroll
      dataLength={items.length}
      next={fetchMoreData}
      hasMore={hasMore}
      loader={<h4>Loading...</h4>}
    >
      {items.map((item, index) => (
        <div key={index}>{item.content}</div>
      ))}
    </InfiniteScroll>
  );
}

性能优化建议

  • 添加防抖逻辑避免频繁触发加载
  • 在组件卸载时清除事件监听
  • 实现数据缓存避免重复请求
  • 对长列表使用react-windowreact-virtualized虚拟滚动

错误处理

需考虑网络请求失败的情况:

react实现滚动分页

const loadMoreItems = async () => {
  try {
    setLoading(true);
    const newItems = await fetchItems(page);
    setItems(prev => [...prev, ...newItems]);
    setPage(prev => prev + 1);
  } catch (error) {
    console.error('Failed to load items:', error);
  } finally {
    setLoading(false);
  }
};

标签: 分页react
分享给朋友:

相关文章

如何手写一个react

如何手写一个react

手写一个简单的 React 创建一个基础的 React 实现需要理解其核心概念:虚拟 DOM、组件、状态管理和渲染。以下是一个简化版的 React 实现。 创建虚拟 DOM 虚拟 DOM 是真实 D…

react如何更新

react如何更新

更新 React 版本的方法 检查当前 React 版本 运行以下命令查看项目中安装的 React 版本: npm list react 更新 React 及相关依赖 通过 npm 或 yarn…

typescript react 如何

typescript react 如何

TypeScript 与 React 结合使用的方法 在 React 项目中使用 TypeScript 可以提升代码的可维护性和类型安全性。以下是一些关键步骤和最佳实践: 安装 TypeScript…

js 实现分页

js 实现分页

实现分页的基本逻辑 分页功能通常需要后端返回数据总量或总页数,前端根据当前页码和每页条数截取对应数据。以下是一个基于JavaScript的简单分页实现方案: 前端分页实现 假设已有从后端获取的完整数…

react如何获取光标

react如何获取光标

获取光标位置的方法 在React中获取光标位置通常涉及处理输入框或文本区域的onChange或onSelect事件。以下是几种常见的方法: 通过selectionStart和selectionEnd…

jquery分页

jquery分页

jQuery分页的实现方法 jQuery分页可以通过多种方式实现,以下是几种常见的方法: 使用插件实现分页 jQuery有许多优秀的分页插件,如jQuery Pagination、DataTabl…