useEndReached
Infinite-loading trigger
A small, fetching-agnostic hook that fires a callback once the last rendered item nears the end of your loaded data. It never fetches anything itself — you wire the callback to whatever data layer you use (TanStack Query, SWR, Apollo, a raw loader). It pairs with useMasonry but works with any { index }[] list.
The <Masonry> component wires this hook internally via its onEndReached prop. For end-to-end examples of both flavors, see the Infinite Loading guide.
function useEndReached(
items: Pick<VirtualItem, 'index'>[],
dataLength: number,
onEndReached: () => void,
options?: UseEndReachedOptions // { threshold?: number; disabled?: boolean }
): void;Parameters
items
- Type:
Pick<VirtualItem, 'index'>[]
The rendered items — pass useMasonry().items. The hook only reads .index of the last entry.
dataLength
- Type:
number
The length of your full data array. The trigger compares the last rendered index against this.
onEndReached
- Type:
() => void
Called when the last rendered index reaches the threshold. Fetching-agnostic — the hook never fetches; pass your loader (fetchNextPage, setSize, fetchMore) directly.
options.threshold
- Type:
number - Default:
0
How close the last rendered index may get to the end of dataLength before firing. 0 fires once the final item of data actually renders.
options.disabled
- Type:
boolean - Default:
false
Hard-suppresses firing. Wire it to your in-flight / has-more state (isFetchingNextPage, !hasNextPage) — the hook does not track fetch state itself.
Notes
The hook depends on the last rendered index (a primitive), not the items array, because useMasonry().items has a fresh identity every render — depending on the array would re-run the effect every render. Batched range-loading and sparse (isItemLoaded) loading are intentionally out of scope; compose them yourself if a large overscan or slow network needs them.