Infinite Scrolling vs. Pagination In react with Complete Example

infinite scroll
Spread the love

When it comes to displaying large datasets on the web, two popular techniques are infinite scrolling and pagination. Both methods serve the purpose of reducing the initial load time and improving the user experience, but they differ in their approach and implementation. In this blog post, we’ll explore the pros and cons of each technique, discuss and an example of their efficient handling in React applications.

What is Infinite Scrolling?

Infinite scrolling, also known as “lazy loading” or “endless scrolling,” is a technique that dynamically loads content as the user scrolls down the page. Instead of displaying all the data at once, the content is loaded in chunks or batches, providing a seamless and uninterrupted browsing experience.

Advantages of Infinite Scrolling

  1. Improved User Experience: Infinite scrolling eliminates the need for clicking on “Next” or “Previous” buttons, creating a more natural and fluid browsing experience.
  2. Reduced Initial Load Time: By loading content in smaller batches, the initial page load time is significantly reduced, leading to a faster and more responsive application.
  3. Suitable for Continuous Content: Infinite scrolling works well for content that can be displayed in a continuous stream, such as social media feeds, news articles, or e-commerce product listings.

Disadvantages of Infinite Scrolling

  1. Potential Performance Issues: Loading excessive amounts of content can lead to performance issues, especially on slower networks or less powerful devices.
  2. Lack of Orientation: Users may lose track of their position within the content since there are no clear page boundaries or numbers.
  3. Accessibility Challenges: Users relying on keyboard navigation or screen readers may find infinite scrolling more challenging to navigate.

What is Pagination?

Pagination is a technique that divides a large dataset into smaller, manageable chunks or pages. Users can navigate through these pages using “Previous” and “Next” buttons or by selecting a specific page number.

Advantages of Pagination

  1. Clear Navigation: Pagination provides a clear sense of orientation and navigation, making it easier for users to understand their position within the content.
  2. Improved Performance: By loading only a limited amount of data at a time, pagination can improve overall performance, especially for data-intensive applications.
  3. Accessibility-Friendly: Pagination is generally more accessible for users relying on keyboard navigation or screen readers.

Disadvantages of Pagination

  1. Interruptions: You have to keep clicking buttons to see more content, which can be annoying.
  2. Slower Initial Load: The first page might take a little longer to load than with infinite scrolling.
  3. Possibility for Repetitious Requests: If not done properly, pagination can keep reloading the same data over and over.

Example of React Infinite Scroll

import React, { useState, useEffect } from 'react';

function App() {

const [todos, setTodos] = useState([]);

const [currentPage, setCurrentPage] = useState(1);

const itemsPerPage = 10;

useEffect(() => {

// Fetch data from the to-do list API

fetch(`https://jsonplaceholder.typicode.com/todos?\_page=${currentPage}&\_limit=${itemsPerPage}\`)

.then((response) => response.json())

.then((data) => {

// Append new data to the existing todos

setTodos([...todos, ...data]);

});

}, [currentPage]);

const handleScroll = () => {

const scrollY = window.scrollY;

const windowHeight = window.innerHeight;

const documentHeight = document.documentElement.scrollHeight;

if (scrollY + windowHeight >= documentHeight - 100) {

setCurrentPage(currentPage + 1);

}

};

useEffect(() => {

window.addEventListener('scroll', handleScroll);

return () => {

window.removeEventListener('scroll', handleScroll);

};

}, [currentPage]);

return (

<div>

<ul>
{todos.map((todo,i) => (

<li key={i}>{todo.content}</li>
))}

</ul> </div>
);

}

export default App;

Let’s breakdown this Example

Import the necessary React hooks:

import React, { useState, useEffect } from 'react';

We define a functional component called App.

Inside the App component, we initialize two state variables using the useState hook

  • todos: An array to store the to-do list items.
  • currentPage: A number representing the current page of data being fetched.

We also define a constant itemsPerPage to specify how many items should be fetched per page (in this case, 10).

The first useEffect hook is used to fetch data from the to-do list API (https://jsonplaceholder.typicode.com/todos) whenever the currentPage value changes. It constructs a URL with the current page number and the items per page limit, fetches the data, and appends the new data to the existing todos array using the spread operator […todos, …data].

useEffect(() => {
  fetch(`https://jsonplaceholder.typicode.com/todos?_page=${currentPage}&_limit=${itemsPerPage}`)
    .then((response) => response.json())
    .then((data) => {
      setTodos([...todos, ...data]);
    });
}, [currentPage]);

The handleScroll function is defined to check if the user has scrolled to the bottom of the page. If they have, it increments the currentPage state variable, which will trigger the useEffect hook to fetch the next page of data.

const handleScroll = () => {
  const scrollY = window.scrollY;
  const windowHeight = window.innerHeight;
  const documentHeight = document.documentElement.scrollHeight;

  if (scrollY + windowHeight >= documentHeight - 100) {
    setCurrentPage(currentPage + 1);
  }
};

The second useEffect hook is used to add an event listener for the scroll event on the window object. This event listener calls the handleScroll function whenever the user scrolls. The cleanup function returned by this hook removes the event listener when the component unmounts.

useEffect(() => {
  window.addEventListener('scroll', handleScroll);

  return () => {
    window.removeEventListener('scroll', handleScroll);
  };
}, [currentPage]);

Finally, the component renders a list of to-do items using the todos array. Each item is rendered as an
<li> element with the todo.content as its content.

return (
  <div>
    {/* Display to-do list items */}
    <ul>
      {todos.map((todo,i) => (
        <li key={i}>{todo.content}</li>
      ))}
    </ul>
  </div>
);

When the App component mounts, it fetches the initial page of data from the API. As the user scrolls to the bottom of the page, the handleScroll function is triggered, which increments the currentPage state variable. This, in turn, triggers the useEffect hook to fetch the next page of data from the API, and the new data is appended to the todos array, causing the component to re-render with the updated list of to-do items.

This example shows how to implement infinite scrolling using React hooks and the fetch API. It fetches data from an API in batches, appends the new data to the existing array, and re-renders the component with the updated list of items as the user scrolls to the bottom of the page.

Example of React Pagination

import React, { useState, useEffect } from 'react';

const MyComponent = () => {
  const [data, setData] = useState([]);
  const [currentPage, setCurrentPage] = useState(1);
  const [totalPages, setTotalPages] = useState(0);

  useEffect(() => {
    // Load data based on the current page
    fetchData(currentPage);
  }, [currentPage]);

  const fetchData = async (page) => {
    // Load data for the specified page
    // Update data and totalPages based on the response
  };

  const handlePageChange = (page) => {
    setCurrentPage(page);
  };

  return (
    <div>
      {/* Render your data */}
      <Pagination
        currentPage={currentPage}
        totalPages={totalPages}
        onPageChange={handlePageChange}
      />
    </div>
  );
};

Let’s Breakdown this pagination example

First, we import the necessary React hooks

import React, { useState, useEffect } from 'react';

We define a functional component called MyComponent.

Inside the MyComponent, we initialize three state variables using the useState hook:

  • data: An array to store the data fetched from the API.
  • currentPage: A number representing the current page of data being displayed.
  • totalPages: A number representing the total number of pages available.

We use the useEffect hook to load data from the API whenever the currentPage value changes. The fetchData function is called with the currentPage value as an argument.

useEffect(() => {
  fetchData(currentPage);
}, [currentPage]);

The fetchData function is defined as an asynchronous function. This function is responsible for fetching data from the API based on the specified page number. It should also update the data and totalPages state variables based on the response from the API.

const fetchData = async (page) => {
  // Load data for the specified page
  // Update data and totalPages based on the response
};

Note: The actual implementation of fetchData is not provided in this example, but it should include code to fetch data from an API and update the state variables accordingly.

The handlePageChange function is defined to update the currentPage state variable when the user navigates to a different page.

const handlePageChange = (page) => {
  setCurrentPage(page);
};

Inside the return statement, we render the data and a Pagination component. The Pagination component is likely a custom component or a third-party library component that renders pagination controls (e.g., page numbers, “Next” and “Previous” buttons).

return (
  <div>
    {/* Render your data */}
    <Pagination
      currentPage={currentPage}
      totalPages={totalPages}
      onPageChange={handlePageChange}
    />
  </div>
);

The Pagination component is expected to receive three props:

  • currentPage: The current page number.
  • totalPages: The total number of pages available.
  • onPageChange: A callback function that is called when the user navigates to a different page. This function is expected to update the currentPage state variable.

Here’s how the pagination flow works:

  1. When the component mounts, the useEffect hook is triggered with the initial currentPage value (1).
  2. The fetchData function is called with the initial currentPage value, fetching the data for the first page from the API.
  3. The data and totalPages state variables are updated based on the response from the API.
  4. The component renders the fetched data and the Pagination component with the current page number and total pages.
  5. When the user interacts with the Pagination component (e.g., clicks on a page number or “Next” button), the handlePageChange function is called with the new page number.
  6. The handlePageChange function updates the currentPage state variable with the new page number.
  7. The useEffect hook is triggered again due to the change in currentPage, and the fetchData function is called with the new page number.
  8. The data and totalPages state variables are updated based on the new response from the API.
  9. The component re-renders with the updated data and pagination controls.

Some Important Links


Spread the love

Similar Posts