Implementing Infinite Scrolling in React Using Intersection Observer

Vasu Bhalodi
Stackademic
Published in
3 min readMay 1, 2024

--

Introduction

Infinite scrolling is a popular technique used in web applications to provide a seamless user experience by loading content dynamically as the user scrolls down the page. In this tutorial, we’ll explore how to implement infinite scrolling in a React.js application using the intersection observer API, without relying on external libraries.

Why Infinite Scrolling?

Traditional pagination methods involve clicking through numbered pages to access additional content. However, infinite scrolling offers a smoother browsing experience by dynamically loading content as the user reaches the end of the current content. This creates a seamless flow for users, eliminating the need for manual navigation and providing a more engaging experience.

Intersection Observer vs. Inbuilt Libraries

When it comes to implementing infinite scrolling, developers have the option of using inbuilt libraries or leveraging modern web APIs like Intersection Observer. While inbuilt libraries offer convenience, they often come with additional dependencies and may not always align perfectly with project requirements. On the other hand, the Intersection Observer API provides a native, performant solution for observing changes in the intersection of DOM elements with a containing element or viewport. It offers flexibility and efficiency, making it an ideal choice for implementing infinite scrolling.

GitHub Code and Live Demo

  • Before we dive into the implementation details, you can access the complete code for this tutorial on GitHub: GitHub Repository.
  • Additionally, you can see the live demo of the infinite scrolling feature in action here: Live Demo.

Explaining the Code

Now, let’s break down the implementation of infinite scrolling using the Intersection Observer API in React.js:

// Import necessary dependencies
import React, { useRef, useEffect, useState } from 'react';

const InfiniteScroll = ({ fetchMoreData }) => {
const [isLoading, setIsLoading] = useState(false);
const sentinelRef = useRef(null);

const { data, page, isInitialCall, hasMore } = useSelector(
(state) => state.imageKey);

useEffect(() => {
if (hasMore) {
dispatch(fetchImage({ page: page, limit: limit }));
}
}, [dispatch, page, hasMore]);

useEffect(() => {
const options = {
root: null,
rootMargin: '0px',
threshold: 1.0,
};

const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting && !isLoading) {
setIsLoading(true);
fetchMoreData().then(() => {
setIsLoading(false);
});
}
}, options);

if (sentinelRef.current) {
observer.observe(sentinelRef.current);
}

return () => {
if (sentinelRef.current) {
observer.unobserve(sentinelRef.current);
}
};
}, [isLoading, fetchMoreData]);

return (
<div>
{/* Render your list of items */}
{/* Place a sentinel element at the end */}
<div ref={sentinelRef}></div>
{isLoading && <p>Loading...</p>}
</div>
);
};

export default InfiniteScroll;

Explanation

We start by importing necessary dependencies and defining our Infinite Scroll component.

  • Within the component, we initialize state variables using the useState hook. isLoading state tracks whether data is currently being loaded.
  • We create a reference (sentinelRef) using the useRef hook. This will be attached to a sentinel element placed at the end of the content.
  • In the useEffect hook, we instantiate an Intersection Observer with specified options. We observe changes in the intersection of the sentinel element with the viewport.
  • When the sentinel element intersects with the viewport and data is not currently loading (isLoading is false), we trigger the fetchMoreData function to load additional content. We update the isLoading state to true during data fetching.
  • Once data is fetched, we reset the isLoading state to false.
  • We return the JSX, rendering the list of items and the sentinel element. Additionally, we display a loading indicator if data is currently being fetched.

Result

Conclusion

In this tutorial, we’ve explored the implementation of infinite scrolling in a React.js application using the Intersection Observer API. By leveraging this modern web API, we can achieve efficient and performant infinite scrolling functionality without relying on external libraries. This approach enhances user experience by seamlessly loading content as the user scrolls, providing a smoother and more engaging browsing experience.

References

Stackademic 🎓

Thank you for reading until the end. Before you go:

--

--

React JS | Redux Toolkit | React Redux | Flutter | Express | DBMS | MySQL | MongoDB | Data Structure