useInfiniteScroll
無限滚動
useInfiniteScroll 偵測使用者何時捲動到容器的邊緣,並觸發回呼以載入更多內容。它接受一個可捲動元素的 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;
}