React Query Easy to add Pagination
Tags: react, javascript, tutorial, webdev
Published: 2022-10-18 12:36:29

## **Pagination**
Pagination is quite use technique to handle website performance in smarter way. Nowadays we often provide infinite scrolling pagination meaning as soon as user scrolled to the bottom new data is fetched or paginate. 

I add this pagination technique on my website [iHateReading](ihatereading.in). The tech stack I was using is react-query for API calls and data caching. 

I've also used the [Browser Intersection API](https://dev.to/shreyvijayvargiya/intersection-observer-api-1901). This API basically helps the browser to track and detect the exclusive DOM element position. Intersection API helps to keep track the DOM element position and invoke the callback method when the threshold is surpassed. 

## Real World Example
- Let's say we have a load more button at the bottom most position of the long list of blogs. 
- Load more button is pressed or comes in the view we will fetch the new data using the API

Intersection API basically helps us to track the load more button view and invoke the callback method at the time of intersection. 

## React Query
React query is a collection of hooks that helps to cache, fetch data in frontend. I will not go into the react-query detail as I've already covered a bunch of stories on it. 

[React Query Shorts introduction](https://studio.youtube.com/video/QW9514m5dlI/edit)

[React query article](https://medium.com/codex/3-steps-to-quickly-start-with-react-query-a3012c62b18b)

## **How to add Pagination**
Let's divide methods into 2 stages one is the API call and another one is the pagination or page number. 

**API call to fetch data**
API call will take the page number from where the element has to be fetched from database. For example, first page will get 10 items followed by page number = 2 will fetch items starting from 11 till 20th item and so on.

```
const {data, isLoading } = useQuery(["blogs"], 
 async() => { 
  const data = await fetchBlogs(pageNumber);
  return data;
 }
);

```

**Page Number**
Page number is tracked and maintained by the UI. As soon as user reach the load more button the intersection API will invoke the callback method and increase the page number by 1. This keeps on happening until the page number reached the last value. 

```
const [pageNumber, setPageNumber] = useState(0);
const [isIntersecting, setIntersecting] = useState(false);
const observer = new IntersectionObserver(([entry]) =>
 setIntersecting(entry.isIntersecting));

useEffect(() => {
 observer.observe(ref.current);
   return () => observer.disconnect();
}, []);

```

**API fetching paginated data**
- As soon as we reached the load more button the `isIntersection` state will change to true
- Callback function of intersection API will get's and page number value will gets increased by one. 
- `useQuery` will again call make the API call by invoking `fetchBlogs` method by passing updated pageNumber value.
Hence our paginated data or next 10 items will get fetched. 
React query will automatically cache this new data to provide better user experience and decrease the number of API calls.

## Conclusion
This is quite easy to implement using react-query and intersection API. Otherwise we would have to track the load more button location everytime user scrolled the webpage followed by increasing the page number and making API call again to fetch next 10 items. 
Becomes bit messy and performance will also get hindered but using react-query and intersection API we are avoiding unnecessary re-rendering improving the application performance. 

Keep developing
Shrey
[iHateReading](ihatereading.in)