Have you ever wondered how social media apps like Instagram manage to keep us scrolling, almost as if the content is endless? I know I have! It goes beyond just great content — it taps into a continuous flow that keeps us hooked, waiting for what’s next. Unlike traditional pagination, where users have to click "Next" to load more, infinite scrolling creates a seamless experience. Just as we reach the end of the visible content, new items load in, sparking curiosity and anticipation. This is the magic of infinite scroll: keeping the journey going without any interruptions. Let’s dive right into it In this guide, we’ll create a simple React app that uses infinite scroll to display GitHub users information. We'll be using: React: For creating and managing the component-based structure of our app. react-infinite-scroll-component: A popular package to manage the infinite scroll behavior. Tailwind CSS: For quick and clean styling. Axios: For making HTTP requests to the GitHub API. 1.) Set Up the Project npx create-react-app infinite-scroll-app cd infinite-scroll-app npm start Install axios, react-infinite-scroll-component and tailwindcss npm install axios react-infinite-scroll-component tailwindcss 2.) Generate a Github Personal Token Since we’ll be using the Github Apis, it’s important to get Access Token from GitHub To avoid rate limitations, Here’s how to create a GitHub Personal Access Token and use it in your project: Go to your GitHub Settings. Click on "Generate new token". Select the scopes you need (for read-only public data, you typically just need the public_repo scope). Generate and copy the token somewhere secure; you’ll need it in your app Create an .env file in the root directory, include the github API url and the Access Token you just copied REACT_APP_API_URL=https://api.github.com REACT_APP_API_KEY=your_access_token 3.) Fetch the data from the Github Api const fetchUsers = async () => { try { const response = await axios.get(`${apiUrl}/users`, { headers: { Authorization: `Bearer ${apiKey}`, }, params: { per_page: 20, // Adjust the number of users per page since: lastUserId, //The user id it should begin listing }, }); const newUsers = response.data; setUsers((prevUsers) => [...prevUsers, ...newUsers]); setLastUserId(newUsers[newUsers.length - 1]?.id); // update the last user ID setHasMore(newUsers.length > 0); } catch (error) { console.error("Error fetching users from GitHub API:", error); return []; } }; It’s important to note that Github uses since and not page just as is in the code above 4.) Setting Up The Infinite Scroll <InfiniteScroll dataLength={users.length} next={fetchUsers} hasMore={hasMore} loader={ <h4 className="font-semibold mt-4 text-center">Loading...</h4> } endMessage={<p>No more users to display</p>} > <div className="flex flex-wrap gap-4 justify-between items-center"> {users.map((user, key) => ( <div key={key} className="border h-[8rem] w-[45%] sm:w-[30%] md:w-[20%] flex flex-col gap-2 items-center p-2" > <img src={user.avatar_url} alt={`Avatar image of ${user.login}`} width="80px" height="80px" className="rounded-full" /> <p>{user.login}</p> </div> ))} </div> </InfiniteScroll> 5. )Putting it all together import axios from "axios"; import React, { useEffect, useState } from "react"; import InfiniteScroll from "react-infinite-scroll-component"; function App() { const [users, setUsers] = useState([]); const [lastUserId, setLastUserId] = useState(null); const [hasMore, setHasMore] = useState(true); const apiKey = process.env.REACT_APP_API_KEY; const apiUrl = process.env.REACT_APP_API_URL; const fetchUsers = async () => { try { const response = await axios.get(`${apiUrl}/users`, { headers: { Authorization: `Bearer ${apiKey}`, }, params: { per_page: 20, // Adjust the number of users per page since: lastUserId, //The user id it should begin listing }, }); const newUsers = response.data; setUsers((prevUsers) => [...prevUsers, ...newUsers]); setLastUserId(newUsers[newUsers.length - 1]?.id); // update the last user ID setHasMore(newUsers.length > 0); } catch (error) { console.error("Error fetching users from GitHub API:", error); return []; } }; useEffect(() => { fetchUsers(); }, []); return ( <div className="container py-8"> <div className="mx-auto"> <h1 className="text-4xl font-bold text-center mb-8"> React Infinite Scroll Demo </h1> <InfiniteScroll dataLength={users.length} next={fetchUsers} hasMore={hasMore} loader={ <h4 className="font-semibold mt-4 text-center">Loading...</h4> } endMessage={<p>No more users to display</p>} > <div className="flex flex-wrap gap-4 justify-between items-center"> {users.map((user, key) => ( <div key={key} className="border h-[8rem] w-[45%] sm:w-[30%] md:w-[20%] flex flex-col gap-2 items-center p-2" > <img src={user.avatar_url} alt={`Avatar image of ${user.login}`} width="80px" height="80px" className="rounded-full" /> <p>{user.login}</p> </div> ))} </div> </InfiniteScroll> </div> </div> ); } export default App; Conclusion Infinite scrolling is a way to keep users engaged by continuously loading new content without interruption, and by now, you’ve experienced how easy it is to add to a React app. Using react-infinite-scroll-component, axios for API calls, and tailwindcss for styling, we’ve created a user-friendly experience that mimics popular social platforms. Find the source code on github. Check the app here. Have you ever wondered how social media apps like Instagram manage to keep us scrolling, almost as if the content is endless? I know I have! It goes beyond just great content — it taps into a continuous flow that keeps us hooked, waiting for what’s next. Unlike traditional pagination, where users have to click "Next" to load more, infinite scrolling creates a seamless experience. Just as we reach the end of the visible content, new items load in, sparking curiosity and anticipation. This is the magic of infinite scroll : keeping the journey going without any interruptions. infinite scroll Let’s dive right into it In this guide, we’ll create a simple React app that uses infinite scroll to display GitHub users information. We'll be using: React: For creating and managing the component-based structure of our app. react-infinite-scroll-component: A popular package to manage the infinite scroll behavior. Tailwind CSS: For quick and clean styling. Axios: For making HTTP requests to the GitHub API. React : For creating and managing the component-based structure of our app. React react-infinite-scroll-component : A popular package to manage the infinite scroll behavior. react-infinite-scroll-component Tailwind CSS : For quick and clean styling. Tailwind CSS Axios : For making HTTP requests to the GitHub API. Axios 1.) Set Up the Project npx create-react-app infinite-scroll-app cd infinite-scroll-app npm start npx create-react-app infinite-scroll-app cd infinite-scroll-app npm start Install axios , react-infinite-scroll-component and tailwindcss axios react-infinite-scroll-component tailwindcss npm install axios react-infinite-scroll-component tailwindcss npm install axios react-infinite-scroll-component tailwindcss 2.) Generate a Github Personal Token Since we’ll be using the Github Apis, it’s important to get Access Token from GitHub To avoid rate limitations, Here’s how to create a GitHub Personal Access Token and use it in your project: Go to your GitHub Settings. Click on "Generate new token". Select the scopes you need (for read-only public data, you typically just need the public_repo scope). Generate and copy the token somewhere secure; you’ll need it in your app Create an .env file in the root directory, include the github API url and the Access Token you just copied Go to your GitHub Settings . GitHub Settings Click on "Generate new token" . "Generate new token" Select the scopes you need (for read-only public data, you typically just need the public_repo scope). public_repo Generate and copy the token somewhere secure; you’ll need it in your app Create an .env file in the root directory, include the github API url and the Access Token you just copied REACT_APP_API_URL=https://api.github.com REACT_APP_API_KEY=your_access_token REACT_APP_API_URL=https://api.github.com REACT_APP_API_KEY=your_access_token 3.) Fetch the data from the Github Api const fetchUsers = async () => { try { const response = await axios.get(`${apiUrl}/users`, { headers: { Authorization: `Bearer ${apiKey}`, }, params: { per_page: 20, // Adjust the number of users per page since: lastUserId, //The user id it should begin listing }, }); const newUsers = response.data; setUsers((prevUsers) => [...prevUsers, ...newUsers]); setLastUserId(newUsers[newUsers.length - 1]?.id); // update the last user ID setHasMore(newUsers.length > 0); } catch (error) { console.error("Error fetching users from GitHub API:", error); return []; } }; const fetchUsers = async () => { try { const response = await axios.get(`${apiUrl}/users`, { headers: { Authorization: `Bearer ${apiKey}`, }, params: { per_page: 20, // Adjust the number of users per page since: lastUserId, //The user id it should begin listing }, }); const newUsers = response.data; setUsers((prevUsers) => [...prevUsers, ...newUsers]); setLastUserId(newUsers[newUsers.length - 1]?.id); // update the last user ID setHasMore(newUsers.length > 0); } catch (error) { console.error("Error fetching users from GitHub API:", error); return []; } }; It’s important to note that Github uses since and not page just as is in the code above since page 4.) Setting Up The Infinite Scroll <InfiniteScroll dataLength={users.length} next={fetchUsers} hasMore={hasMore} loader={ <h4 className="font-semibold mt-4 text-center">Loading...</h4> } endMessage={<p>No more users to display</p>} > <div className="flex flex-wrap gap-4 justify-between items-center"> {users.map((user, key) => ( <div key={key} className="border h-[8rem] w-[45%] sm:w-[30%] md:w-[20%] flex flex-col gap-2 items-center p-2" > <img src={user.avatar_url} alt={`Avatar image of ${user.login}`} width="80px" height="80px" className="rounded-full" /> <p>{user.login}</p> </div> ))} </div> </InfiniteScroll> <InfiniteScroll dataLength={users.length} next={fetchUsers} hasMore={hasMore} loader={ <h4 className="font-semibold mt-4 text-center">Loading...</h4> } endMessage={<p>No more users to display</p>} > <div className="flex flex-wrap gap-4 justify-between items-center"> {users.map((user, key) => ( <div key={key} className="border h-[8rem] w-[45%] sm:w-[30%] md:w-[20%] flex flex-col gap-2 items-center p-2" > <img src={user.avatar_url} alt={`Avatar image of ${user.login}`} width="80px" height="80px" className="rounded-full" /> <p>{user.login}</p> </div> ))} </div> </InfiniteScroll> 5. )Putting it all together import axios from "axios"; import React, { useEffect, useState } from "react"; import InfiniteScroll from "react-infinite-scroll-component"; function App() { const [users, setUsers] = useState([]); const [lastUserId, setLastUserId] = useState(null); const [hasMore, setHasMore] = useState(true); const apiKey = process.env.REACT_APP_API_KEY; const apiUrl = process.env.REACT_APP_API_URL; const fetchUsers = async () => { try { const response = await axios.get(`${apiUrl}/users`, { headers: { Authorization: `Bearer ${apiKey}`, }, params: { per_page: 20, // Adjust the number of users per page since: lastUserId, //The user id it should begin listing }, }); const newUsers = response.data; setUsers((prevUsers) => [...prevUsers, ...newUsers]); setLastUserId(newUsers[newUsers.length - 1]?.id); // update the last user ID setHasMore(newUsers.length > 0); } catch (error) { console.error("Error fetching users from GitHub API:", error); return []; } }; useEffect(() => { fetchUsers(); }, []); return ( <div className="container py-8"> <div className="mx-auto"> <h1 className="text-4xl font-bold text-center mb-8"> React Infinite Scroll Demo </h1> <InfiniteScroll dataLength={users.length} next={fetchUsers} hasMore={hasMore} loader={ <h4 className="font-semibold mt-4 text-center">Loading...</h4> } endMessage={<p>No more users to display</p>} > <div className="flex flex-wrap gap-4 justify-between items-center"> {users.map((user, key) => ( <div key={key} className="border h-[8rem] w-[45%] sm:w-[30%] md:w-[20%] flex flex-col gap-2 items-center p-2" > <img src={user.avatar_url} alt={`Avatar image of ${user.login}`} width="80px" height="80px" className="rounded-full" /> <p>{user.login}</p> </div> ))} </div> </InfiniteScroll> </div> </div> ); } export default App; import axios from "axios"; import React, { useEffect, useState } from "react"; import InfiniteScroll from "react-infinite-scroll-component"; function App() { const [users, setUsers] = useState([]); const [lastUserId, setLastUserId] = useState(null); const [hasMore, setHasMore] = useState(true); const apiKey = process.env.REACT_APP_API_KEY; const apiUrl = process.env.REACT_APP_API_URL; const fetchUsers = async () => { try { const response = await axios.get(`${apiUrl}/users`, { headers: { Authorization: `Bearer ${apiKey}`, }, params: { per_page: 20, // Adjust the number of users per page since: lastUserId, //The user id it should begin listing }, }); const newUsers = response.data; setUsers((prevUsers) => [...prevUsers, ...newUsers]); setLastUserId(newUsers[newUsers.length - 1]?.id); // update the last user ID setHasMore(newUsers.length > 0); } catch (error) { console.error("Error fetching users from GitHub API:", error); return []; } }; useEffect(() => { fetchUsers(); }, []); return ( <div className="container py-8"> <div className="mx-auto"> <h1 className="text-4xl font-bold text-center mb-8"> React Infinite Scroll Demo </h1> <InfiniteScroll dataLength={users.length} next={fetchUsers} hasMore={hasMore} loader={ <h4 className="font-semibold mt-4 text-center">Loading...</h4> } endMessage={<p>No more users to display</p>} > <div className="flex flex-wrap gap-4 justify-between items-center"> {users.map((user, key) => ( <div key={key} className="border h-[8rem] w-[45%] sm:w-[30%] md:w-[20%] flex flex-col gap-2 items-center p-2" > <img src={user.avatar_url} alt={`Avatar image of ${user.login}`} width="80px" height="80px" className="rounded-full" /> <p>{user.login}</p> </div> ))} </div> </InfiniteScroll> </div> </div> ); } export default App; Conclusion Infinite scrolling is a way to keep users engaged by continuously loading new content without interruption, and by now, you’ve experienced how easy it is to add to a React app. Using react-infinite-scroll-component , axios for API calls, and tailwindcss for styling, we’ve created a user-friendly experience that mimics popular social platforms. react-infinite-scroll-component axios tailwindcss Find the source code on github . github Check the app here . here