DEV Community

shrey vijayvargiya
shrey vijayvargiya

Posted on

React Query Easy to add Pagination

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. The tech stack I was using is react-query for API calls and data caching.

I've also used the Browser Intersection API. 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

React query article

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;
 }
);

Enter fullscreen mode Exit fullscreen mode

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();
}, []);

Enter fullscreen mode Exit fullscreen mode

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

Top comments (3)

Collapse
 
pcelac profile image
Aleks

Sorry, but this article makes no sense + code is wrong and incomplete. And you have useInfiniteQuery for that purpose.

Collapse
 
shreyvijayvargiya profile image
shrey vijayvargiya

Can you please specify which one is a wrong code, for the facts, I am using the same codebase in our current website.

Yes, I haven't use useInfiniteQuery because it's doesn't feels to use and fit to the title says Easy to add Pagination meaning we don't want to make it complex.

Collapse
 
pcelac profile image
Aleks

You are talking about increasing page number, but nothing is calling setPageNumber , only isIntersecting flag.
In the API call, you are using ["blogs"] as your cache key, which is wrong, as new call won't be triggered when you change pageNumber , etc etc...