Adding Infinite Scroll to Our News App | React JS Tutorial for Beginners 🔄📰
So far, our React News App uses Previous and Next buttons to move between
pages of articles. This works well, but many modern apps — like Twitter, Instagram, and
Google News — use infinite scroll instead: new articles load automatically as the
user scrolls down, with no buttons to click at all.
In this React JS tutorial for beginners, we'll replace manual pagination with infinite
scroll using the popular react-infinite-scroll-component package.
In this tutorial, we will learn:
What infinite scroll is and how it differs from pagination
Installing and using react-infinite-scroll-component
Tracking hasMore data in component state
Appending new articles instead of replacing them
Showing a loading spinner at the bottom while more articles load
Wrapping the article list with <InfiniteScroll>
---
What is Infinite Scroll?
Infinite scroll is a UX pattern where new content loads automatically as the user
approaches the bottom of the page, instead of requiring a click on Next. It removes
the extra step of pagination and keeps users engaged longer — which is why it's so common
in social media and news feeds. Unlike pagination, we no longer track a fixed "page number";
instead, we keep appending new articles to the existing list until there's nothing left
to load.
---
Step 1: Install react-infinite-scroll-component
Open your terminal inside the project folder and install the package:
npm install react-infinite-scroll-component
---
Step 2: Update State to Support Infinite Scroll
Open News.js and remove the fixed page-button logic in favor of a
hasMore flag, which tells us whether more articles are available to load.
import React, { Component } from "react";
import InfiniteScroll from "react-infinite-scroll-component";
import NewsItem from "./NewsItem";
import Spinner from "./Spinner";
export class News extends Component {
static defaultProps = {
pageSize: 6,
totalResults: 30,
};
state = {
articles: [],
page: 1,
hasMore: true,
};
render() {
return (
<div className="container my-4">
<h2 className="text-center mb-4">Welcome to News App 📰</h2>
</div>
);
}
}
export default News;
---
Step 3: Write a fetchMoreArticles Method
This method simulates loading the next batch of articles and appends them to the
existing articles array using the spread operator. It also updates hasMore
once we've reached totalResults.
fetchMoreArticles = () => {
const { pageSize, totalResults } = this.props;
const nextPage = this.state.page + 1;
// Simulated network delay — will be replaced by a real API call later
setTimeout(() => {
const newArticles = [
{
title: `Sample Article ${nextPage}`,
description: "More interesting news loaded via infinite scroll.",
urlToImage: "",
url: "#",
},
];
this.setState({
articles: this.state.articles.concat(newArticles),
page: nextPage,
hasMore: nextPage * pageSize < totalResults,
});
}, 1000);
};
---
Step 4: Wrap the Article List with InfiniteScroll
Now replace the Previous/Next buttons with the <InfiniteScroll> component. It
watches the scroll position and automatically calls next when the user nears the
bottom of dataLength.
render() {
const { articles, hasMore } = this.state;
return (
<div className="container my-4">
<h2 className="text-center mb-4">Welcome to News App 📰</h2>
<InfiniteScroll
dataLength={articles.length}
next={this.fetchMoreArticles}
hasMore={hasMore}
loader={<Spinner />}
>
{articles.map((article, index) => (
<NewsItem
key={index}
title={article.title}
description={article.description}
imageUrl={article.urlToImage}
newsUrl={article.url}
/>
))}
</InfiniteScroll>
</div>
);
}
---
Step 5: Full Updated News.js
Here is the complete News.js file with infinite scroll wired in end-to-end.
import React, { Component } from "react";
import InfiniteScroll from "react-infinite-scroll-component";
import NewsItem from "./NewsItem";
import Spinner from "./Spinner";
export class News extends Component {
static defaultProps = {
pageSize: 6,
totalResults: 30,
};
state = {
articles: [
{
title: "React 19 Released",
description: "React 19 brings exciting improvements for developers.",
urlToImage: "",
url: "#",
},
{
title: "GitHub Pages Hosting Made Easy",
description: "Deploy your React app for free using GitHub Pages.",
urlToImage: "",
url: "#",
},
{
title: "JavaScript ES2025 Features",
description: "Explore the newest JavaScript features landing in 2025.",
urlToImage: "",
url: "#",
},
],
page: 1,
hasMore: true,
};
fetchMoreArticles = () => {
const { pageSize, totalResults } = this.props;
const nextPage = this.state.page + 1;
setTimeout(() => {
const newArticles = [
{
title: `Sample Article ${nextPage}`,
description: "More interesting news loaded via infinite scroll.",
urlToImage: "",
url: "#",
},
];
this.setState({
articles: this.state.articles.concat(newArticles),
page: nextPage,
hasMore: nextPage * pageSize < totalResults,
});
}, 1000);
};
render() {
const { articles, hasMore } = this.state;
return (
<div className="container my-4">
<h2 className="text-center mb-4">Welcome to News App 📰</h2>
<InfiniteScroll
dataLength={articles.length}
next={this.fetchMoreArticles}
hasMore={hasMore}
loader={<Spinner />}
>
{articles.map((article, index) => (
<NewsItem
key={index}
title={article.title}
description={article.description}
imageUrl={article.urlToImage}
newsUrl={article.url}
/>
))}
</InfiniteScroll>
</div>
);
}
}
export default News;
---
Pagination vs Infinite Scroll: Key Differences
| Aspect |
Pagination (Previous/Next) |
Infinite Scroll |
| User Action |
Manual click required |
Automatic on scroll |
| Data Handling |
Replaces the article list each time |
Appends new articles to the existing list |
| Best For |
Structured browsing, e-commerce, search results |
News feeds, social media, content discovery |
| SEO Impact |
Easier to index individual pages |
Requires extra care (e.g., unique URLs) for indexing |
---
Features and Learnings:-
Understood the difference between pagination and infinite scroll.
Installed and configured react-infinite-scroll-component.
Replaced the page-based state with a hasMore flag.
Wrote fetchMoreArticles to append new articles to the existing list.
Displayed a loading spinner automatically at the bottom of the feed.
Wrapped the article list with <InfiniteScroll> for automatic loading.
Prepared the app for the next step: connecting infinite scroll to a real News API.