import { useEffect, useRef, useState, useCallback } from "react"; import { Empty, Spin } from "@arco-design/web-react"; import "./index.css"; const InfiniteScroll = ({ loadMore, hasMore, children, threshold = 0.1, // 触发阈值,元素可见比例 className = "", empty = false, }) => { const containerRef = useRef(null); const sentinelRef = useRef(null); const observerRef = useRef(null); const throttleRef = useRef(null); // 节流控制 const [loading, setLoading] = useState(false); const [hasInitialized, setHasInitialized] = useState(false); // 首次挂载 // 加载更多数据的处理函数(带节流) const handleLoadMore = useCallback(() => { if (loading || !hasMore) return; // 节流处理:500ms内只能触发一次 if (throttleRef.current) { clearTimeout(throttleRef.current); } throttleRef.current = setTimeout(() => { setLoading(true); loadMore().finally(() => { setLoading(false); throttleRef.current = null; }); }, 10); }, [hasMore, loadMore, loading]); // 设置IntersectionObserver useEffect(() => { // 初始化观察器 const options = { root: containerRef.current, rootMargin: "0px 0px 50px 0px", // 减少提前触发距离 threshold, }; // 创建观察器实例 observerRef.current = new IntersectionObserver((entries) => { const [entry] = entries; if (entry.isIntersecting) { handleLoadMore(); } }, options); // 开始观察哨兵元素 if (sentinelRef.current) { observerRef.current.observe(sentinelRef.current); } // 初始加载检查 - 仅在组件首次挂载时执行 if (hasMore && !loading && !hasInitialized) { setHasInitialized(true); handleLoadMore(); } // 清理函数 return () => { if (observerRef.current) { observerRef.current.disconnect(); } // 清理节流定时器 if (throttleRef.current) { clearTimeout(throttleRef.current); throttleRef.current = null; } }; }, [loadMore, hasMore, threshold, loading, hasInitialized, handleLoadMore]); return (