#InfiniteScroll 无限滚动
浏览到列表末尾时加载更多内容。
#基本用法
项目 1
项目 2
项目 3
项目 4
项目 5
项目 6
项目 7
项目 8
项目 9
项目 10
basic.tsx
import { InfiniteScroll, ScrollArea } from '@ifhover/leaf-ui';
import { useRef, useState } from 'react';
export function InfiniteScrollBasic() {
const root = useRef<HTMLDivElement>(null);
const [items, setItems] = useState(() => Array.from({ length: 10 }, (_, i) => i));
return (
<ScrollArea ref={root} height={240} aria-label="动态列表">
<InfiniteScroll
dataLength={items.length}
hasMore={items.length < 40}
target={() => root.current}
onLoadMore={async (signal) => {
await new Promise((resolve) => setTimeout(resolve, 500));
if (!signal.aborted)
setItems((previous) => [
...previous,
...Array.from({ length: 10 }, (_, index) => previous.length + index),
]);
}}
>
{items.map((item) => (
<div key={item} style={{ padding: '12px 16px' }}>
项目 {item + 1}
</div>
))}
</InfiniteScroll>
</ScrollArea>
);
}
#更多用法
记录 1
记录 2
记录 3
记录 4
记录 5
记录 6
advanced.tsx
import { InfiniteScroll, ScrollArea } from '@ifhover/leaf-ui';
import { useRef, useState } from 'react';
export function InfiniteScrollRetry() {
const root = useRef<HTMLDivElement>(null);
const attempt = useRef(0);
const [items, setItems] = useState([0, 1, 2, 3, 4, 5]);
return (
<ScrollArea ref={root} height={180} aria-label="重试示例">
<InfiniteScroll
dataLength={items.length}
hasMore={items.length < 12}
target={() => root.current}
onLoadMore={async (signal) => {
await new Promise((resolve) => setTimeout(resolve, 300));
if (signal.aborted) return;
if (attempt.current++ === 0) throw new Error('Retry demo');
setItems((previous) => [...previous, ...[6, 7, 8, 9, 10, 11]]);
}}
>
{items.map((item) => (
<p key={item}>记录 {item + 1}</p>
))}
</InfiniteScroll>
</ScrollArea>
);
}
#使用说明
onLoadMore 返回 Promise,一次请求期间不会重复触发。追加新数据后更新 dataLength。signal 在卸载时取消请求,失败后可重试。
#类型
组装数据、定义回调和使用 ref 时,可以导入这些类型。
import type { InfiniteScrollProps } from '@ifhover/leaf-ui';#InfiniteScrollProps API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
dataLength | number | 必填 | 已加载数量,变化后允许下一次请求 |
hasMore | boolean | 必填 | 还有后续数据 |
onLoadMore | (signal: AbortSignal) => Promise<void> | 必填 | 加载更多,signal 用于取消请求 |
target | () => HTMLElement | null | — | 滚动目标或链接打开方式 |
threshold | number | 200 | 距离末尾触发加载的像素距离 |
loader | ReactNode | — | 加载占位内容 |
endMessage | ReactNode | — | 全部加载后的内容 |
onError | (error: unknown) => void | — | 异常回调 |