useInfiniteScroll
无限滚动
useInfiniteScroll 基于 useScroll 构建,当用户滚动接近可滚动容器边缘时自动触发回调。传入一个目标元素 ref、一个加载更多函数和可选配置(滚动方向、距离阈值、节流)。加载更多回调接收当前滚动状态,便于你决定是否获取更多数据。该 hook 还支持在前置内容时保留滚动位置。
使用场景
- 构建在用户滚动时加载更多项目的信息流、时间线或产品列表
- 实现滚动到顶部时加载更早消息的聊天界面
- 创建按需获取额外内容的水平滚动画廊
注意事项
- SSR 安全:该 hook 在服务端渲染期间为空操作。服务端不会附加滚动监听器。
- 方向:默认在
bottom边缘触发。使用direction选项在top、left或right边缘触发,用于反向或水平滚动。 - 相关 hooks:基于
useScroll构建,后者提供底层的滚动位置、方向和到达状态跟踪。
Usage
Live Editor
function Demo() { const ref = useRef<HTMLDivElement>(null); const [data, setData] = useState([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); useInfiniteScroll( ref, () => { const length = data.length + 1; const newData = data.slice(); if (newData.length === 400) { return; } newData.push(...Array.from({ length: 5 }, (_, i) => length + i)); setData(newData); }, { distance: 10 }, ); return ( <div> <div ref={ref} style={{ width: 300, height: 300, overflow: "scroll" }}> {data.map(item => ( <div key={item} style={{ padding: 12, border: "1px solid" }}> 项目-{item} </div> ))} </div> </div> ); };
Result
API
useInfiniteScroll
Returns
void
Arguments
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| target | dom元素 | BasicTarget<Element> (必填) | - |
| onLoadMore | 加载更多函数 | UseInfiniteScrollLoadMore (必填) | - |
| options | 可选参数 | UseInfiniteScrollOptions | undefined | - |
UseInfiniteScrollLoadMore
Returns
void | Promise<void>
Arguments
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| state | useScroll 返回的状态 | readonly [number, number, boolean, UseInfiniteScrollArrivedState, UseInfiniteScrollDirection] (必填) | - |
UseInfiniteScrollOptions
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| distance | 元素底部与视口底部之间的最小距离 | number | 0 |
| direction | 滚动方向 | 'top' | 'bottom' | 'left' | 'right' | 'bottom' |
| preserveScrollPosition | 加载更多项目时是否保留当前滚动位置 | boolean | - |
| throttle | 滚动事件的节流时间,默认关闭。 | number | 0 |
| idle | 滚动结束时的检查时间。当配置 throttle 时,此配置将设置为 (throttle +idle)。 | number | - |
| offset | 将到达状态偏移 x 像素 | UseScrollOffset | - |
| onScroll | 滚动的回调 | (e: Event) => void | - |
| onStop | 滚动结束的回调 | (e: Event) => void | - |
| eventListenerOptions | 滚动事件参数 | boolean | AddEventListenerOptions | {capture: false, passive: true} |
UseInfiniteScrollArrivedState
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| left | 到达左边 | boolean (必填) | - |
| right | 到达右边 | boolean (必填) | - |
| top | 到达顶部 | boolean (必填) | - |
| bottom | 到达底部 | boolean (必填) | - |
UseInfiniteScrollDirection
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| left | 向左滚动 | boolean (必填) | - |
| right | 向右滚动 | boolean (必填) | - |
| top | 向上滚动 | boolean (必填) | - |
| bottom | 向下滚动 | boolean (必填) | - |
BasicTarget
export type BasicTarget<T extends TargetType = Element> = (() => TargetValue<T>) | TargetValue<T> | MutableRefObject<TargetValue<T>>;
TargetValue
type TargetValue<T> = T | undefined | null;
TargetType
type TargetType = HTMLElement | Element | Window | Document | EventTarget;
UseScrollOffset
export interface UseScrollOffset {
left?: number;
right?: number;
top?: number;
bottom?: number;
}