feat: 🎸 重新封装了滚动加载/解决了一个引用bug
This commit is contained in:
@@ -6,41 +6,61 @@ const InfiniteScroll = ({
|
||||
loadMore,
|
||||
hasMore,
|
||||
children,
|
||||
threshold = 50,
|
||||
threshold = 0.1, // 触发阈值,元素可见比例
|
||||
className = "",
|
||||
empty = false,
|
||||
}) => {
|
||||
const containerRef = useRef(null);
|
||||
const sentinelRef = useRef(null);
|
||||
const observerRef = useRef(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [hasInitialized, setHasInitialized] = useState(false); // 首次挂载
|
||||
|
||||
// 加载更多数据的处理函数
|
||||
const handleLoadMore = () => {
|
||||
if (loading || !hasMore) return;
|
||||
|
||||
const handleScroll = () => {
|
||||
if (loading) return;
|
||||
setLoading(true);
|
||||
if (!containerRef.current || !hasMore) return;
|
||||
|
||||
const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
|
||||
|
||||
if (scrollTop + clientHeight >= scrollHeight - threshold) {
|
||||
loadMore().finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
}
|
||||
loadMore().finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
// 设置IntersectionObserver
|
||||
useEffect(() => {
|
||||
const container = containerRef.current;
|
||||
if (container) {
|
||||
container.addEventListener("scroll", handleScroll);
|
||||
// 初始加载时检查是否需要加载更多
|
||||
handleScroll();
|
||||
// 初始化观察器
|
||||
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 (container) {
|
||||
container.removeEventListener("scroll", handleScroll);
|
||||
if (observerRef.current) {
|
||||
observerRef.current.disconnect();
|
||||
}
|
||||
};
|
||||
}, [loadMore, hasMore, threshold]);
|
||||
}, [loadMore, hasMore, threshold, loading]);
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -49,6 +69,9 @@ const InfiniteScroll = ({
|
||||
>
|
||||
{children}
|
||||
|
||||
{/* 哨兵元素 - 用于触发加载更多 */}
|
||||
<div ref={sentinelRef} className="sentinel-element"></div>
|
||||
|
||||
{!hasMore && empty && (
|
||||
<Empty description="暂无数据" className="empty-data" />
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user