当前位置:首页 > React

react实现无限加载

2026-01-26 21:38:33React

无限加载的实现原理

无限加载的核心逻辑是通过监听滚动事件或交叉观察器(Intersection Observer)判断用户是否滚动到页面底部,触发数据加载。React中可以通过自定义Hook或第三方库简化实现。

使用Intersection Observer API

Intersection Observer是现代浏览器提供的API,性能优于传统的滚动事件监听。以下是一个基础实现示例:

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

function useInfiniteScroll(fetchCallback) {
  const [isFetching, setIsFetching] = useState(false);
  const observerRef = useRef(null);

  useEffect(() => {
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting && !isFetching) {
          setIsFetching(true);
          fetchCallback().finally(() => setIsFetching(false));
        }
      },
      { threshold: 0.1 }
    );

    if (observerRef.current) observer.observe(observerRef.current);

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

  return [observerRef, isFetching];
}

实际应用示例

结合数据获取的完整组件实现:

react实现无限加载

function InfiniteList() {
  const [items, setItems] = useState([]);
  const [page, setPage] = useState(1);

  const fetchMoreItems = async () => {
    const newItems = await fetch(`/api/items?page=${page}`);
    setItems(prev => [...prev, ...newItems]);
    setPage(prev => prev + 1);
  };

  const [loaderRef, isFetching] = useInfiniteScroll(fetchMoreItems);

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

性能优化建议

添加防抖机制避免频繁触发

const debouncedFetch = useMemo(
  () => debounce(fetchMoreItems, 300),
  [fetchMoreItems]
);

缓存已加载数据

react实现无限加载

const cachedItems = useMemo(
  () => new Set(items.map(item => item.id)),
  [items]
);

错误处理增强

在fetch回调中添加错误处理

const fetchMoreItems = async () => {
  try {
    const newItems = await fetch(`/api/items?page=${page}`);
    if (newItems.length === 0) {
      setHasMore(false);
      return;
    }
    setItems(prev => [...prev, ...newItems]);
    setPage(prev => prev + 1);
  } catch (error) {
    setError(error.message);
  } finally {
    setIsFetching(false);
  }
};

第三方库方案

如需快速实现,可考虑成熟库:

  • react-infinite-scroller
  • react-waypoint
  • react-intersection-observer

这些库封装了底层细节,提供更丰富的功能如节流控制、自定义触发阈值等。

标签: 加载react
分享给朋友:

相关文章

如何手写一个react

如何手写一个react

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

react如何调试

react如何调试

调试 React 应用的方法 使用 React Developer Tools React Developer Tools 是 Chrome 和 Firefox 的浏览器扩展,可以检查组件树、状态和…

react如何遍历

react如何遍历

遍历数组或对象的方法 在React中,遍历数组或对象通常用于渲染列表或动态生成内容。以下是几种常见的遍历方法: 使用map遍历数组map是遍历数组并返回新数组的高阶函数,适合渲染列表。…

react 如何调试

react 如何调试

调试 React 应用的方法 使用 React Developer Tools 安装 Chrome 或 Firefox 的 React Developer Tools 扩展,可以检查组件树、状态和 p…

如何提高react

如何提高react

优化性能 使用React.memo对组件进行记忆化处理,避免不必要的重新渲染。对于类组件,可以使用PureComponent来达到类似效果。 利用useMemo缓存计算结果,避免重复计算。对于函数或…

vue加载动画实现

vue加载动画实现

Vue 加载动画实现方法 使用 CSS 动画或过渡 在 Vue 组件中可以直接通过 CSS 实现加载动画效果。定义一个简单的旋转动画: .loading-spinner { width: 40p…