Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Query useQueries hook to run useInfiniteQuery hooks in parallel

Tags:

react-query

I am new to React-Query, but I have not been able to find an example to the following question:

  • Is it possible to use useInfiniteQuery within useQueries?

I can see from the parallel query documentation on GitHub, that it's fairly easy to set-up a map of normal queries.

The example provided:

function App({ users }) {
  const userQueries = useQueries({
    queries: users.map(user => {
      return {
        queryKey: ['user', user.id],
        queryFn: () => fetchUserById(user.id),
      }
    })
  })
}

If I have an infinite query like the following, how would I be able to provide the individual query options, specifically the page parameter?:

  const ids: string[] = ['a', 'b', 'c'];

  const useGetDetailsById = () => {
    return useInfiniteQuery<GetDetailsByIdResponse, AxiosError>(
      ['getDetailsById', id],
      async ({ pageParam = '' }) => {
        const { data } = await getDetailsById(
          id, // I want to run queries for `id` in _parallel_
          pageParam
        );
        return data;
      },
      {
        getNextPageParam: (lastPage: GetDetailsByIdResponse) =>
          lastPage.nextPageToken,
        retry: false,
      }
    );
  };
like image 377
Torc Avatar asked Nov 07 '25 12:11

Torc


2 Answers

No, I'm afraid there is currently no such thing as useInfiniteQueries.

like image 60
TkDodo Avatar answered Nov 09 '25 09:11

TkDodo


I've solved this for my use case by using one useInifiniteQuery to handle paging, and the fetch function uses queryClient to get the array of network requests.

// Use ReactQuery to fetch array with cache
function fetchPage(
  queryClient: QueryClient,
  urls: string[],
  pageParam: PageParams
) {
  const requests = urls.map(url => {
    return queryClient
      .fetchQuery({
        queryKey: ['/api/endpoint', url],
        queryFn: () => fetchURL(url),
      })
      .catch(error => {
        throw error
      })
  })
  return Promise.all(requests)
}

// Component handles paging with one useInfiniteQuery
export default function Page() {
  const [urls, setUrls] = useState<string[]>([
    ...
  ])

  const queryClient = useQueryClient()
  const {
    data: pagedData,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
  } = useInfiniteQuery({
    queryKey: ['page', urls],
    queryFn: ({ pageParam }) => fetchPage(queryClient, urls, pageParam),
    initialPageParam: { ... },
    getNextPageParam: (lastPage, allPages, lastPageParam) => { ... }
    retry: Infinity,
  })

  const data = useMemo(() => {
    return pagedData?.pages...
  }, [pagedData])

  ...
like image 26
Michael Ozeryansky Avatar answered Nov 09 '25 10:11

Michael Ozeryansky



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!