Infinite scrolling is a popular UI pattern that allows content to be loaded dynamically as users scroll down a page. Adding loading indicators to indicate that more content is being loaded enhances the user experience. In this blog post, we will discuss how to create a custom useInfiniteScrollWithLoading
hook in React, which combines infinite scrolling functionality with loading indicators.
Table of Contents
- Introduction
- Setting up the Project
- Implementing the
useInfiniteScrollWithLoading
Hook - Using the Hook in a Component
- Conclusion
Introduction
Infinite scrolling can be achieved by using the Intersection Observer API
, which allows us to observe when an element enters or exits the viewport. Additionally, we can use loading indicators, such as spinners or progress bars, to show that content is being loaded.
Setting up the Project
To get started, make sure you have Node.js and npm installed on your machine. Create a new React project using the create-react-app
CLI or any other method you prefer.
Once your project is set up, let’s install the required dependencies:
npm install react@latest react-dom@latest
Implementing the useInfiniteScrollWithLoading
Hook
Create a new file called useInfiniteScrollWithLoading.js
and define the custom hook:
import { useEffect, useRef, useState } from 'react';
const useInfiniteScrollWithLoading = (loadMore) => {
const [isLoading, setIsLoading] = useState(false);
const loaderRef = useRef(null);
useEffect(() => {
const options = {
root: null,
rootMargin: '20px',
threshold: 0.8,
};
const handleIntersection = (entries) => {
const target = entries[0];
if (target.isIntersecting && !isLoading) {
setIsLoading(true);
loadMore();
}
};
const observer = new IntersectionObserver(handleIntersection, options);
if (loaderRef.current) {
observer.observe(loaderRef.current);
}
return () => {
if (loaderRef.current) {
observer.unobserve(loaderRef.current);
}
};
}, [isLoading, loadMore]);
return [loaderRef, isLoading];
};
export default useInfiniteScrollWithLoading;
The useInfiniteScrollWithLoading
hook takes a loadMore
function as a parameter, which will be called when the loader element is intersected with the viewport. It returns a reference to the loader element (loaderRef
) and a boolean value indicating whether content is currently being loaded (isLoading
).
Using the Hook in a Component
Now, let’s see how we can use the useInfiniteScrollWithLoading
hook in a component. Assume we have an ArticleList
component that displays a list of articles. When the user scrolls to the bottom of the page, we want to load more articles and display a loading spinner while the request is being processed.
import React, { useState } from 'react';
import useInfiniteScrollWithLoading from './useInfiniteScrollWithLoading';
const ArticleList = () => {
const [articles, setArticles] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const loadMoreArticles = async () => {
// Simulating an API call to fetch more articles
const response = await fetch(`https://api.example.com/articles?page=${currentPage + 1}`);
const newArticles = await response.json();
// Update the state with the new articles
setArticles([...articles, ...newArticles]);
setCurrentPage(currentPage + 1);
};
const [loaderRef, isLoading] = useInfiniteScrollWithLoading(loadMoreArticles);
return (
<div>
{articles.map((article) => (
// Render each article item
<div key={article.id}>{article.title}</div>
))}
{/* Render the loading indicator */}
{isLoading && <div ref={loaderRef}>Loading...</div>}
</div>
);
};
export default ArticleList;
In this example, the loadMoreArticles
function is responsible for fetching more articles from an API and updating the list of articles in the state. We pass this function as a parameter to the useInfiniteScrollWithLoading
hook.
We then render each article item and display the loading indicator by checking the value of isLoading
. The loaderRef
is assigned to the ref
attribute of the loading element, allowing the Intersection Observer to observe it.
Conclusion
In this blog post, we discussed how to create a custom useInfiniteScrollWithLoading
hook in React to implement infinite scrolling with loading indicators. By combining the Intersection Observer API
with loading indicators, we can enhance the user experience by providing real-time feedback when more content is being loaded. Feel free to customize the hook to suit your specific needs and add additional features. Happy scrolling!
#react #scrolling
Click here to download the source code for this project.