Infinite list loading 🤔, with React Query - useInfiniteQuery hook !
Tags: react, reactquery, webdev, javascript
Published: 2024-07-09 03:18:11

Sometimes getting all the data in a single API query is worth than getting it in the form of paginated data, but not in every case what if you need the API to be more optimized and efficient hence implementing a infinite loading kind of a feature from scratch might not only be complicated but also overwhelming if you are just a beginner in React, Let's see how react-query makes it possible with the help of infinite queries.

Hello I am [SHREY](https://x.com/shreykoradia), your author and the guide to put you up on a step closer on mastering react-query with implementing infinite loading list feature from scratch with the help of react-query.

So now if we see, for example real world application like [Dribble ](https://dribbble.com/), we may find a `Browse More Inspiration` kind of a button at the bottom of the screen after some amount of web mockups are displayed, so on clicking that button we may find more amount of data displayed again and the cycle continues.

So one way is we give a button and on the click of it we may find a set of data thrown at the client from the server or otherwise we could make the use of infinite queries with the help of scroll in that case we may need to use [react-intersection-observer](https://www.npmjs.com/package/react-intersection-observer) to get new data based on the viewport and scroll trigger.

Lets build the feature with a button saying load more data, without furthure ado 😅.

So Let us define how we could get the data from the backend, for example different api handles pagination differently, in my case I have limit and offset kind of a thing where developer from frontend handles limit of data they want with the help of offset, so my response structure from backend would be somewhat like the below example stated:

```
{
  "feedbacks": {
    "totalPages": 1,
    "feedbacks": [
      {
        "_id": "6624d529440d8153b9967515",
        "feedback": "Hehe cool think to do",
        "feedback_author_id": "6621e2621755214cca2e300b",
        "feedback_author_name": "test1",
        "tale_id": "65f6bbd6feec14b3e8804846",
        "created_at": "2024-04-21T08:58:17.963Z",
        "__v": 0
      },
      {
        "_id": "662afb1caca2a90e470bc78f",
        "feedback": "sddsdsdd",
        "feedback_author_id": "65b38594f8211ed0962fe067",
        "feedback_author_name": "shrey",
        "tale_id": "65f6bbd6feec14b3e8804846",
        "created_at": "2024-04-26T00:53:48.653Z",
        "__v": 0
      },
      {
        "_id": "662afb34aca2a90e470bc79c",
        "feedback": "xoxo",
        "feedback_author_id": "65b38594f8211ed0962fe067",
        "feedback_author_name": "shrey",
        "tale_id": "65f6bbd6feec14b3e8804846",
        "created_at": "2024-04-26T00:54:12.671Z",
        "__v": 0
      }
    ]
  }
}

```

Now I will be having a backend api endpoint in somewhat this fashion where user can attach limit and offset in the form of query params

```
http://localhost:3000/v1/feedback/get-feedbacks?taleId=123&offset=12&limit=6
```

Okay so my only point of stating this was to get easily think how our hasNextPage params work in frontend when we try to apply it using inifite queries. 

lets see how we need to handle react-query hook called `useInfiniteQuery`

```
 const fetchFeedbacks = ({ pageParam = 0 }) => {
    return getFeedbacks({ taleId: params.taleId, offset: pageParam });
  };

 const query = useInfiniteQuery({
    queryKey: ["get-feedbacks", params?.taleId],
    queryFn: fetchFeedbacks,
    initialPageParam: 0,
    getNextPageParam: (lastPage, lastPageParam) => {
      if (lastPage.data.feedbacks.feedbacks.length === 0) {
        return undefined;
      }
      return lastPageParam.length * LIMIT;
    },
    enabled: !!params?.taleId,
  });

```

In this above piece of code we have assigned our values returning from the useInfinteQuery to a variable where we already have known in our previous blogs about the queryKey , queryFn etc but here we see `initalPageParam `, this is a parameter required by default when using this hook which helps in fetching the first page we set it to 0 and hence this will get us the first page data from the backend server. Hence when the api endpoints get fired the offset in the api endpoint tends to be 0 and the data actually is fetch from the 0th index or in layman terms we say page.

`getNextPageParam` is a callable function which return a single variable in the docs it is described something like this:

When new data is received for this query, this function receives both the last page of the infinite list of data and the full array of all pages, as well as pageParam information. 

so how did I used getNextPageParam is similar to what written above, this means lastPage with the data returned by the API endpoint **if having length === 0 than I will return undefined stating that there is no more data that can be sent back to client from the server ** otherwise I will be returning the next page param which will get us the data from the backend server  lastPageParam.length * LIMIT, I have also added how I would get the lastPageParam and what I will be returning , offset is what will be returned by `lastPageParam.length * LIMIT`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3k2c3mlwmv6ny0gsmqgw.png)

and you already know what enabled is and how do we already use it and why we use it. If you are not familiar to the enabled keyword you know the drill => get to my previous [blogs ](https://dev.to/delisrey/series/24656)and dig the docs to find out what enabled does.

There are also other set of parameter where you could use it with useInfiniteQuery such as getPreviousPageParam and maxPages you could dig a deeper view it on the react-query docs but getPreviousPages does the similar thing as getNextPageParams but it takes `firstPage, allPages, firstPageParam, allPageParams` firstPage and firstPage params while maxPages is the number of pages to be stored in the infinite query data.

This is how it will display it, I have recorded a prime use case from one of my product that i am gonna make it enable to use for the new users for 
brainstorming and creating story boards for the application soon.

https://jam.dev/c/0b3c18fd-d250-4bc5-96fb-69d01ce7f915

This was all for now, I know I am not curating a blog every week like the way I used to curate before, but I will try my best. Also lets not forget to like and share the blog with others and comment any good or optimized way to handle the react query  useInfiniteQuery hook I would love to know your feedbacks as well, 

btw Hello once again I am SHREY, Part-time SDE at Talez (hacking on my product) otherwise I do a full time Software Development at an early scale start-up if you reached till here reading the blog do follow me and yeah have a happy working week Bye:)