Last active
November 5, 2025 14:48
-
-
Save isocroft/762fe55cd2c453d221205a099bd888e1 to your computer and use it in GitHub Desktop.
React Infinite Scroll Hook using react-query and react-busser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { useEffect, useRef } from "react"; | |
| import { useIsDOMElementVisibleOnScreen } from "react-busser"; | |
| import type { InfiniteQueryResult, InfiniteQueryKey, InfiniteQueryFunction, InfiniteQueryOptions } from "react-query"; | |
| import { useInfiniteQuery } from "react-query"; | |
| export type InfiniteScrollQueryOptions<TK, TR, TMV, TE> = { | |
| queryKey: InfiniteQueryKey<TK>; | |
| queryFn?: InfiniteQueryFunction<TR, TK, TMV>; | |
| config?: InfiniteQueryOptions<TR, TMV, TE>; | |
| }; | |
| export function useInfiniteScrollForQueries <K, D, T, E = Error>(queryOptions: InfiniteScrollQueryOptions<K, D, T, E>, scrollOptions = { rootMargin: "0px", threshold: 1 }) { | |
| const { fetchNextPage, hasNextPage, ...query } = useInfiniteQuery(queryOptions); | |
| const [ isIntersecting, domElementRef ] = useIsDOMElementVisibleOnScreen(scrollOptions); | |
| /* @HINT: Use the latest ref pattern */ | |
| const fetcher = useRef(fetchNextPage); | |
| useEffect(() => { | |
| fetcher.current = fetchNextPage; | |
| }); | |
| useEffect(() => { | |
| if (isIntersecting && hasNextPage) { | |
| fetcher.current(); | |
| } | |
| }, [isIntersecting, hasNextPage]); | |
| const queryResult = { ...query, hasNextPage, fetchNextPage } as InfiniteQueryResult<D, T, E>; | |
| return [queryResult, domElementRef] as const; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment