Have you been struggling with this question too when working on your React project? Whether to choose the endless streams of infinite scrolling or provide structure to your oasis with pagination? I always find myself in the peril of deciding which option is better for efficient data handling in React applications.
If you think about it, even Google shifted from Pagination to Infinite Scrolling and one very apparent benefit that I’ve experienced myself is the fact that I tend to scroll past the first 10 or the first ‘SERP’ page to find more relevant articles with lower SERP rankings.
The same is the concept with one of the most popular React applications – Instagram! Have you ever found yourself aimlessly scrolling through those addictive reels, swiping one after the other infinitely? This endless abundance of content encourages discovery and reduces friction, providing a seamless user experience.
However, is infinite scrolling a one-size-fits-all solution, or Pagination is a better alternative for efficient data management in some React applications? Today, I will try to break down both these data management techniques and weigh their pros and cons so you know when to use them.
Let’s get started:
The focus of infinite scrolling is to provide a seamless and dynamic user experience to users when working with huge data chunks. By allowing users to endlessly scroll through a stream of endless content without requiring them to load new pages to access more content, your users are motivated to stay and navigate your site or application for longer.
However, this isn’t ideal for all situations and can have its pitfalls if not understood properly. Let’s understand the pros and cons of infinite scrolling in React to get a clearer idea –
Infinite scrolling promotes a seamless and engaging user experience without any interruptions of clicking pagination buttons or links.
Infinite scrolling triggers page load when the user scrolls down the page to view more content, hence it only loads the first frame of content that needs to be displayed on the first load request. This reduces the initial load time significantly.
Scrolling is way more comfortable and user-friendly than tapping as it has a lower interaction cost. You can scroll through pages faster than clicking buttons. If you have a lengthy content structure for whitepapers or tutorials, infinite scrolling can provide better usability compared to breaking down the text in several sections and providing them with their separate pages or screens.
The idea of loading massive data on the fly as the user scrolls through your page can lead to performance bottlenecks especially for users that use devices with limited capacities or bandwidth connections. The browser can struggle to keep up with the performance demands of the ever-growing stream of data, resulting in lags and a sluggish user experience.
The infinite scroll pattern can cause serious challenges from an accessibility point of view, as screen readers and other such assistive tools can have difficulty keeping focus on the user’s current location. The ARIA Authoring Practices Guide by W3.org talks about this in greater detail. It also limits keyboard navigation which can be problematic for users who can’t use a mouse.
One of the most overlooked perils of infinite scrolling is the absence of a footer. The footer plays a significant role in any website. It provides quick access to important links for users who want to find something or navigate to another page. With infinite scrolling, the user will never reach the footer as they will find more content each time they scroll down the page.
Pagination is a more structured approach to a user interface pattern. It divides your huge datasets into multiple pages where each page has a distinctive start and end. This approach allows users to easily navigate where they are, and move to the next page when they want to. It is easier to keep track of what the user has seen and what is left to be seen. Hence, navigation is much more organized with Pagination in React.
While Pagination solves many of infinite scrolling limitations, it’s not without its demerits.
Let’s get a better understanding of the pros and cons of Pagination:
Pagination is ideal for situations where the user is ‘searching’ for something specific from a list of results and not endlessly scrolling content without any motive. Hence, when you visit ecommerce sites such as Amazon, you’ll always find pagination in their product listing pages with the numbers tab at the bottom. Even online newspapers and magazines like The New York Times and discussion platforms like Reddit or Stack Overflow use pagination to display their threads and discussions.
Pagination limits the number of items that get rendered on each page and loads only a single page at a time. This reduces the performance overhead and lag that infinite scroll implementations can experience with slower devices and limited bandwidth connections.
Pagination is easier for people dependent on assistive technologies such as screen readers. Screen readers can easily identify and announce page changes which helps the visually impaired users to better navigate through the content while understanding the data structure.
Pagination provides a clear and systematic navigation system for users. It can be done through numbered pages, arrows, or any other such design element that allows users to jump to a particular section, switch between different pages or go back to the specific product/service they wanted.
Pagination does put disruptions on the user flow, especially for React websites where the main goal is continuous browsing and discovery are the primary goals. Having to click the button ‘Load More’ or numbered pages can cause interruptions which breaks the tendency of immersion.
Pagination also focuses on pushing the most important and closer to the query results on the first few pages so users get instant access to what they are looking for. This can lead to situations where users might never navigate to pages beyond the 3rd or 4th count. This results in wasted server resources fetching data for pages that don’t ever get viewed.
Pagination provides a structured framework and this approach doesn’t sit well with applications that want to promote continuous discovery and browsing. Imagine the UI of Pinterest if it asked you to change the page after one or two scrolls to view more Pins or ideas. That would be an absolute nightmare and kill the purpose of the app.
Both Infinite Scrolling and Pagination have different approaches to creating an engaging, user-friendly, and performance-oriented user experience. I believe that understanding the use cases and considerations for each approach is crucial for developers who want to optimize usability, accessibility, and performance in their React applications. Which is pretty much, every React developer ever.
Hence, I have outlined some of the most popular use cases and matched them with the most suitable approach, which can help you make a quick and informed decision next time you’re stuck in the same loop.
Infinite Scroll in React is designed to boost user engagement and increase the overall time visitors stay on your website. If you think your audience base consists of people who don’t have a particular goal in mind, they could be easily kept busy with easy, digestible, and interruption-free content. Pagination is designed to help users reach their desired search results as soon as possible. Hence it won’t work best with apps that want to promote content discovery and exploration.
If your React app is paginated it allows users to visit and navigate your site with ease. Also, returning customers get a sense of familiarity and comfort knowing your site’s static layout. A successful pagination effort aims to reduce the number of clicks to reach their desired location and fulfill their goal of visiting the website.
On the contrary, if your site is better-suited to exploration and content discovery, infinite scrolling can help improve your ease of use significantly. It is fast, responsive, and highly intuitive. Discovery-based application users would appreciate the seamless user experience.
Generally, website builders provide default support for pagination for structuring your content. To implement pagination in React you need to track the current page number and number of items per page. Rendering the list of items based on the current page number can still be easily manageable. You can also make use of pagination libraries for React like Material-UI Pagination and Paginate to make the process even easier.
Most of the time pagination is available out of the box too. However, setting up support for infinite scrolling can be challenging and often requires the assistance of a reliable Reactjs development company that has access to skilled developers who can help you with your project.
import React, { useState, useEffect } from "react";
import Posts from "./components/Posts";
import Pagination from "./components/Pagination";
import axios from "axios";
import "./style.css";
const App = () => {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(false);
const [currentPage, setCurrentPage] = useState(1);
const [postsPerPage] = useState(10);
useEffect(() => {
const fetchPosts = async () => {
setLoading(true);
const res = await axios.get("https://jsonplaceholder.typicode.com/posts");
setPosts(res.data);
setLoading(false);
};
fetchPosts();
}, []);
// get current post
const indexOfLastPost = currentPage * postsPerPage; // 1 * 10 = 10
const indexOfFirstPost = indexOfLastPost - postsPerPage; // 10 - 10 = 0
const currentPosts = posts.slice(indexOfFirstPost, indexOfLastPost); // 0 to 10
const paginate = (pageNumber) => setCurrentPage(pageNumber);
return (
<div>
<h3> Api Pagination in React </h3>{" "}
<Posts posts={currentPosts} loading={loading} />{" "}
<Pagination
postsPerPage={postsPerPage}
totalPosts={posts.length}
paginate={paginate}
/>{" "}
</div>
);
};
export default App;
./components.Posts
) and (./components/Pagination
)
useState
hook for creating three state variables:postsPerPage
to define number of posts displayed per page. (for instance, 10 in this example).
useEffect
hook with an empty dependency array ([]) will run once the component mounts.fetchPosts
that:GET
request using axios to the JSONPlaceholder
API endpoint (https://jsonplaceholder.typicode.com/posts).fetchPosts
inside the useEffect
hook for triggering initial data fetch.
postsPerPage
and currentPage
.currentPosts
variable.
pageNumber
argument and updates the currentPage state using setCurrentPage. This triggers re-rendering of the App component, recalculating currentPosts
and reflecting the page change in the UI.
currentPosts
for displaying and loading state for conditional rendering.import { useEffect } from "react";
import { useInfiniteQuery } from "react-query";
import { useInView } from "react-intersection-observer";
import Todo from "./Todo";
import "./App.css";
function App() {
const { ref, inView } = useInView();
const LIMIT = 10;
const fetchTodos = async (page) => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/todos?_page=${page}&_limit=${LIMIT}`,
);
return response.json();
};
const { data, hasNextPage, fetchNextPage, isFetchingNextPage } =
useInfiniteQuery("todos", ({ pageParam = 1 }) => fetchTodos(pageParam), {
getNextPageParam: (lastPage, allPages) => {
const nextPage =
lastPage.length === LIMIT ? allPages.length + 1 : undefined;
return nextPage;
},
});
useEffect(() => {
if (inView && hasNextPage) {
fetchNextPage();
}
}, [inView, fetchNextPage, hasNextPage]);
return (
<div className="app">
{data?.pages?.map((page) =>
page?.map((todo, i) => {
if (page.length === i + 1) {
return (
<Todo
{...(page.length === i + 1 && { ref: ref })}
key={todo.id}
todo={todo}
/>
);
}
return <Todo key={todo.id} todo={todo} />;
}),
)}
{isFetchingNextPage && <h3>Loading...</h3>}
</div>
);
}
export default App;
useEffect
from React for managing side effects in functional components.useInView
from react-intersection-observer:
Detects when an element enters the viewport../Todo.js
): Renders individual TODO items../App.css
(optional): CSS styles for the application.
Defines the functional component App.
const { ref, inView } = useInView():
inView
using useInView. This helps detect when the element referenced by ref enters the viewport.const LIMIT = 10:
Defines the number of TODO items fetched per page.
fetchTodos(page):
fetchTodos
that takes a page number as input.
const { data, hasNextPage, fetchNextPage, isFetchingNextPage } = useInfiniteQuery(...):
Uses useInfiniteQuery for infinite data fetching.
Queries data with the key "todos".
Provides a query function that takes an options object:
options.pageParam = 1
: Sets the initial page number (default 1).
Calls fetchTodos
with the current pageParam
to fetch data.
This returns an object containing:
data
: The fetched TODO data (paginated).
hasNextPage
: A boolean indicating if more pages are available.
fetchNextPage
: A function to fetch the next page of data.
isFetchingNextPage
: A boolean indicating if the next page is being fetched.
useEffect(() => { ... }, [inView, fetchNextPage, hasNextPage])
:inView, fetchNextPage, or hasNextPage
changes.inView
), there are more pages (hasNextPage
), and the next page is not currently being fetched (!isFetchingNextPage
).fetchNextPage
to load the next page of TODOs.
isFetchingNextPage
is true, shows a "Loading...”, shows a “Loading…” message.
I believe both infinite scrolling and pagination offer viable options for handling large datasets in React applications. The optimal choice would depend on your specific project needs and the user experience you aim to achieve.
Here is a quick recap:
Infinite Scrolling is ideal for continuous, exploration-oriented content where users don’t have a specific search item in mind. It promotes a seamless browsing experience but it can impact performance with huge datasets. Consider implementing techniques like lazy loading or virtualization to mitigate performance bottlenecks.
Pagination is better suited for goal-oriented applications where users are actively looking for specific content. It provides more control over navigation but at the cost of less immersion for continuous content.