Infinite loading, also known as endless scrolling, is a popular technique used in web development to provide a seamless browsing experience by dynamically loading content as users scroll down a page. In this blog post, we'll explore three different methods to implement infinite loading in React with TypeScript: using a library, manually with Intersection Observer API, and manually with scroll event listeners.
Using a Library: react-infinite-scroll-component
React developers often turn to libraries to streamline the implementation of complex features. One such library for infinite loading in React is react-infinite-scroll-component. It is one of the most popular library in 2024
Now let see how to do it with the simple example code below:
import React, { useState } from 'react';
import InfiniteScroll from 'react-infinite-scroll-component';
const InfiniteList: React.FC = () => {
const [items, setItems] = useState<number[]>(Array.from({ length: 20 }));
const fetchMoreData = () => {
// Simulate fetching more data (e.g., from an API)
setTimeout(() => {
setItems(prevItems => [...prevItems, ...Array.from({ length: 20 })]);
}, 1500);
};
return (
<InfiniteScroll
dataLength={items.length}
next={fetchMoreData}
hasMore={true}
loader={<h4>Loading...</h4>}
endMessage={<p>No more items to load</p>}
>
{items.map((item, index) => (
<div key={index} style={{ marginBottom: '20px' }}>
Item {index + 1}
</div>
))}
</InfiniteScroll>
);
};
export default InfiniteList;
For more information on react-infinite-scroll-component
, you can refer to the documentation here react-infinite-scroll-component/docs/README-3.0.2.md at d5b4e5250669022db5217763afd22fb3995a505a ยท ankeetmaini/react-infinite-scroll-component (github.com)
Using Intersection Observer API:
The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport. This makes it ideal for implementing infinite scrolling without relying on a library.
You can read more the docs about this API here: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
Now let take a look the example code below to see how to do it:
import React, { useState, useEffect, useRef } from 'react';
const InfiniteScroll: React.FC = () => {
const [items, setItems] = useState<number[]>([]);
const [isLoading, setIsLoading] = useState<boolean>(false);
const observer = useRef<IntersectionObserver | null>(null);
useEffect(() => {
const fetchData = async () => {
setIsLoading(true);
// Simulate fetching data from an API
const response = await fetch('https://api.example.com/data');
const newData: number[] = await response.json();
setItems(prevItems => [...prevItems, ...newData]);
setIsLoading(false);
};
observer.current = new IntersectionObserver(entries => {
if (entries[0].isIntersecting && !isLoading) {
fetchData();
}
});
observer.current.observe(document.querySelector('#load-more'));
return () => {
if (observer.current) {
observer.current.disconnect();
}
};
}, [isLoading]);
return (
<div>
{items.map((item, index) => (
<div key={index}>{item}</div>
))}
{isLoading && <div>Loading...</div>}
<div id="load-more" style={{ height: '20px' }}></div>
</div>
);
};
export default InfiniteScroll;
Manually with Scroll Event Listeners:
Although using libraries or APIs can simplify the implementation process, sometimes a manual approach is preferred for greater control over the behavior. Implementing infinite loading with scroll event listeners is one such manual method.
import React, { useState, useEffect } from 'react';
const InfiniteScroll: React.FC = () => {
const [items, setItems] = useState<number[]>([]);
const [isLoading, setIsLoading] = useState<boolean>(false);
useEffect(() => {
const fetchData = async () => {
setIsLoading(true);
// Simulate fetching data from an API
const response = await fetch('https://api.example.com/data');
const newData: number[] = await response.json();
setItems(prevItems => [...prevItems, ...newData]);
setIsLoading(false);
};
const handleScroll = () => {
if (
window.innerHeight + document.documentElement.scrollTop ===
document.documentElement.offsetHeight &&
!isLoading
) {
fetchData();
}
};
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, [isLoading]);
return (
<div>
{items.map((item, index) => (
<div key={index}>{item}</div>
))}
{isLoading && <div>Loading...</div>}
</div>
);
};
export default InfiniteScroll;
Conclusion:
Infinite loading is a powerful technique to improve user experience by providing seamless content loading as users scroll down a webpage. Whether you choose to utilize a library like react-infinite-scroll-component
, leverage the Intersection Observer API, or implement it manually with scroll event listeners, each approach offers its own benefits and flexibility. Experiment with these methods to find the one that best suits your project requirements and development preferences.
Happy coding!
Discussion (undefined)