How to Create Infinite Scroll with useQuery

Tulusibrahim
3 min readJun 30, 2023
Photo by Noah Silliman on Unsplash

Yep I know there is useInfiniteQuery API provided by react query, but now I want to try if this works with useQuery as well. In this case I use https://dummyjson.com/ API to mock the data and react-intersection-observer to detect if the page is in the bottom or not.

Here’s how it done. First setup the query client provider in the app.tsx

Within the Product component, we define fetch product function to provide to queryFn

Here in the function, we use try catch block to handle the error gracefully. Notice that within the URL we give limit query param, this to indicate how many items we will fetch within a single API request. Here we define the state for limit with initial value of 5. So later on when the limit is added up it will fetch more items according to the limit.

Now let’s define the useQuery to hit the API and get the data

In the return, we map through the data to display if the loading is false. Just for simplicity we just show the image and title of the product

If we run the app, it will run like normal, but nothing happens when we scroll until the bottom of the page. Here the react-intersection-observer is come into play. It will detect if some element is within the viewport by attach a ref to the element. Here is how to do it

inView value is a boolean that represent whether the element in viewport or not, and we add it to array dependency in useEffect. Notice that we need to add ref to an element that we want to depend on, which is the loading text in this case. Every time the inView value change, we add the limit by 5, refetch it, and the item will add up once the request is done.

In this case, everytime the limit is added and refetch happen, the previous data that already in the page will always be there because the refetch is just incrementally add the limit and the response will also include the previous data. This will slightly different when the for example the param is page=2 probably we need to store the products within the state, and everytime the refetch success we need to merge the existing array with previous data with the new data because it is all different from the previous fetch.

Full working code:

--

--

Tulusibrahim

Frontend engineer, usually post some thought once in a while.