Introduction
If you have ever used apps like Instagram, LinkedIn, or YouTube, you already know how smooth the experience feels when content keeps loading as you scroll. You don’t click buttons. You don’t wait for a new page. Everything just flows.
That experience is powered by something called infinite scrolling.
Now, if you are building a React application that shows a large list of data — like products, posts, or articles — you will face a common problem:
Loading everything at once makes your app slow
Pagination breaks user flow
Users lose interest when they have to click again and again
This is exactly where infinite scrolling becomes useful.
In this article, we’ll not just implement it, but actually understand how it works, why it matters, and how to build it the right way in React with real-world thinking.
What is Infinite Scrolling?
Infinite scrolling is a UI pattern where new data automatically loads when the user reaches near the bottom of the page.
Instead of saying:
“Click next page”
your app says:
“Here’s more content… keep scrolling.”
Real-life example
Think about social media apps:
You never think about pages — you just consume content.
That’s exactly the goal.
Why Do We Use Infinite Scrolling?
Let’s understand the problem first.
Without Infinite Scrolling (Traditional Pagination)
User clicks page 1 → loads
Clicks page 2 → waits again
Clicks page 3 → gets frustrated
This breaks the flow.
With Infinite Scrolling
Real-world impact
E-commerce → Users browse more products
Social apps → Users spend more time
Content platforms → Higher retention
Infinite Scroll vs Pagination
| Feature | Infinite Scrolling | Pagination |
|---|
| User Experience | Smooth and continuous | Click-based navigation |
| Speed Perception | Feels faster | Feels slower |
| User Control | Less control | More control |
| SEO | Harder to index | Easier to index |
| Best Use Case | Feeds, apps, social content | Blogs, search pages |
How Infinite Scrolling Actually Works
Let’s break it down in simple thinking:
Show initial data
Watch user scroll behavior
Detect when user is near bottom
Fetch more data
Append it to existing list
And repeat.
It’s basically a loop:
Scroll → Fetch → Append → Scroll again
Step-by-Step Implementation in React
Now let’s build it step by step.
Step 1: Create Basic Component
First, we need a place to store data and render it.
import React, { useState, useEffect } from "react";
function App() {
const [items, setItems] = useState([]);
const [page, setPage] = useState(1);
return (
<div>
<h1>Infinite Scroll Example</h1>
{items.map((item, index) => (
<p key={index}>{item.title}</p>
))}
</div>
);
}
export default App;
What’s happening here?
At this stage, nothing is “infinite” yet — just basic setup.
Step 2: Fetch Data from API
Now we load data whenever page changes.
useEffect(() => {
fetch(`https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=10`)
.then((res) => res.json())
.then((data) => {
setItems((prev) => [...prev, ...data]);
});
}, [page]);
Why this matters
Instead of replacing data, we append it.
👉 This is the core idea of infinite scrolling.
If we don’t append, old data disappears.
Step 3: Detect When User Reaches Bottom
Now the key question:
How does React know the user has scrolled enough?
We listen to the scroll event.
useEffect(() => {
const handleScroll = () => {
const bottomReached =
window.innerHeight + document.documentElement.scrollTop >=
document.documentElement.offsetHeight - 100;
if (bottomReached) {
setPage((prev) => prev + 1);
}
};
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
Simple explanation
That’s it.
Step 4: Add Loading State (Very Important)
Without this, users won’t know what’s happening.
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
fetch(`https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=10`)
.then((res) => res.json())
.then((data) => {
setItems((prev) => [...prev, ...data]);
setLoading(false);
});
}, [page]);
Show loader:
{loading && <p>Loading more data...</p>}
Why this matters
Without a loader:
With loader:
Step 5: Prevent Multiple API Calls
Here’s a real problem.
Scroll events fire many times.
This can cause:
Multiple API calls
Duplicate data
Performance issues
Solution idea
Step 6: Use Intersection Observer (Better Approach)
Scroll events work, but they are not the best solution.
A smarter way is using Intersection Observer.
import { useRef } from "react";
const loader = useRef(null);
useEffect(() => {
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
setPage((prev) => prev + 1);
}
});
if (loader.current) {
observer.observe(loader.current);
}
return () => observer.disconnect();
}, []);
Add this at bottom:
<div ref={loader}></div>
Why this is better
Real-World Scenario (Before vs After)
Without Infinite Scroll
User:
Scrolls → stops
Clicks next → waits
Loses interest
With Infinite Scroll
User:
Scrolls continuously
Content keeps coming
Stays engaged longer
This directly improves business metrics.
Best Practices (Very Important)
Always use backend pagination
Limit number of items per request
Show loading indicators
Handle API errors
Avoid loading too much data at once
Prefer Intersection Observer over scroll
Advantages of Infinite Scrolling
Smooth user experience
Higher engagement
Faster initial load
Ideal for large datasets
Disadvantages of Infinite Scrolling
Harder for SEO indexing
Difficult navigation (no page numbers)
Can overload memory if not handled properly
Footer becomes hard to reach
Common Mistakes to Avoid
When Should You Use Infinite Scrolling?
Use it when:
Avoid it when:
Summary
Infinite scrolling in React is not just about loading data — it’s about creating a smooth and engaging user experience. By detecting scroll position, fetching paginated data, and appending it intelligently, you can build applications that feel fast and modern. Using better techniques like Intersection Observer and following best practices ensures your implementation is efficient and scalable. When used correctly, infinite scrolling can significantly improve user engagement and application performance.