当前位置:首页 > React

react实现滚动分页

2026-01-26 22:13:12React

实现滚动分页的基本思路

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

使用Intersection Observer API

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

react实现滚动分页

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)优化:

react实现滚动分页

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虚拟滚动

错误处理

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

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
分享给朋友:

相关文章

vue  实现分页

vue 实现分页

实现分页的基本思路 在Vue中实现分页通常需要结合后端API返回的数据和前端的分页组件。分页的核心逻辑包括计算总页数、处理当前页码变化以及触发数据请求。 分页组件示例 使用Element UI的分…

分页用vue实现

分页用vue实现

分页用 Vue 实现 在 Vue 中实现分页功能通常需要结合数据管理和 UI 组件。以下是几种常见的方法: 使用 Vue 组件库的分页组件 许多 Vue UI 组件库(如 Element UI、V…

vue实现选项卡分页

vue实现选项卡分页

实现选项卡分页的基本思路 在Vue中实现选项卡分页功能,可以通过动态组件或条件渲染结合数据绑定完成。核心逻辑是维护一个当前激活的选项卡状态,根据用户点击切换内容。 使用v-if条件渲染 通过v-i…

react如何取消渲染

react如何取消渲染

取消渲染的方法 在React中,取消渲染通常指的是在某些条件下阻止组件渲染或中断正在进行的渲染过程。以下是几种常见的方法: 条件渲染 通过条件判断决定是否渲染组件或部分内容。可以使用if语句或三元运…

电脑如何安装react

电脑如何安装react

安装 Node.js 和 npm React 依赖于 Node.js 和 npm(Node Package Manager)。从 Node.js 官网下载并安装最新稳定版本,安装完成后会自动包含 np…

分页实现vue

分页实现vue

分页实现方法(Vue) 使用Element UI分页组件 安装Element UI库后,可以直接使用其分页组件。在模板中添加el-pagination,通过v-model绑定当前页码,设置page-s…