Editor’s note: This article was last updated by Elijah Agbonze on 18 February 2025.
Infinite scrolling is a powerful technique that improves user experience by loading content dynamically. In this guide, we’ll walk through three different ways to implement infinite scrolling in React, including both custom-built and library-based solutions.
The most common method to implement infinite scroll is to use prebuilt React libraries such as react-infinite-scroll-component
and react-window-infinite-loader
:
<span class="hljs-keyword">import</span> InfiniteScroll <span class="hljs-keyword">from</span> "react-infinite-scroll-component"; <span class="hljs-keyword">import</span> { useState, useEffect } <span class="hljs-keyword">from</span> 'react'; <span class="hljs-keyword">function</span> App() { <span class="hljs-keyword">const</span> [page, setPage] = useState(<span class="hljs-number">1</span>); <span class="hljs-keyword">const</span> [products, setProducts] = useState<any[]>([]); <span class="hljs-keyword">const</span> [totalProducts, setTotalProducts] = useState(<span class="hljs-number">0</span>); <span class="hljs-keyword">const</span> fetchData = async (page: <span class="hljs-built_in">number</span>) => { <span class="hljs-keyword">try</span> { <span class="hljs-keyword">const</span> res = await fetch( `https://dummyjson.com/products/?limit=10&skip=${(page - 1) * 10}` ); <span class="hljs-keyword">const</span> data = await res.json(); <span class="hljs-keyword">if</span> (res.ok) { setProducts((prevItems) => [...prevItems, ...data.products]); page === <span class="hljs-number">1</span> && setTotalProducts(() => data.total); } } <span class="hljs-keyword">catch</span> (error) { console.log(error) } }; useEffect(() => { <span class="hljs-keyword">let</span> subscribed = <span class="hljs-literal">true</span>; (async () => { <span class="hljs-keyword">if</span> (subscribed) { await fetchData(<span class="hljs-number">1</span>); } })(); <span class="hljs-keyword">return</span> () => { subscribed = <span class="hljs-literal">false</span>; }; }, []); <span class="hljs-keyword">const</span> handleLoadMoreData = () => { setPage((prevPage) => { <span class="hljs-keyword">const</span> nextPage = prevPage + <span class="hljs-number">1</span>; fetchData(nextPage); <span class="hljs-keyword">return</span> nextPage; }); }; <span class="hljs-keyword">return</span> ( <InfiniteScroll dataLength={products.length} next={handleLoadMoreData} hasMore={totalProducts > products.length} loader={<p>Loading...</p>} endMessage={<p>No more data to load.</p>} > <div> {products.map((product) => ( <div key={product.id}> <h2> {product.title} - {product.id} </h2> </div> ))} </div> </InfiniteScroll> ); }
However, there are multiple ways to achieve the infinite scroll effect. In this guide, we’ll explore three unique approaches to implementing infinite scrolling in React applications:
react-infinite-scroll-component
and react-window-infinite-loader
, which helps save time and effort while still offering customization optionsInfinite scroll eliminates the need for traditional pagination. Instead of navigating through many pages, users can scroll nonstop to view more content, making the experience more engaging and intuitive.
Infinite scroll is widely used in social media platforms like Instagram, X, and TikTok, enabling users to endlessly browse through feeds of images and videos without interruption.
Now that we’ve established what infinite scroll is, let’s proceed with the tutorial.
First we would set up a foundation that will be consistently implemented across all the various infinite scrolling techniques.
To get started, let’s first set up a React application using Vite. In your terminal, run the following commands:
npm create vite@latest ecommerce-app -- --template react-ts cd ecommerce-app npm i
The commands above will generate a React application in TypeScript and install all dependencies. Next, we’ll set up the initial state for our component in App.tsx
. This includes the list of items to display, the necessary loading and error indicators, and a variable to track the total products available:
<span class="hljs-comment">// App.tsx</span> <span class="hljs-keyword">import</span> React, { useState, useEffect } <span class="hljs-keyword">from</span> 'react'; type ProductItem = { id: <span class="hljs-built_in">number</span>; title: <span class="hljs-built_in">string</span>; description: <span class="hljs-built_in">string</span>; category: <span class="hljs-built_in">string</span>; price: <span class="hljs-built_in">number</span>; rating: <span class="hljs-built_in">number</span>; thumbnail: <span class="hljs-built_in">string</span>; brand: <span class="hljs-built_in">string</span>; discountPercentage: <span class="hljs-built_in">number</span>; }; <span class="hljs-keyword">function</span> App() { <span class="hljs-keyword">const</span> [loading, setLoading] = useState(<span class="hljs-literal">true</span>); <span class="hljs-keyword">const</span> [products, setProducts] = useState<ProductItem[]>([]); <span class="hljs-keyword">const</span> [totalProducts, setTotalProducts] = useState(<span class="hljs-number">0</span>); <span class="hljs-keyword">const</span> [error, setError] = useState<null|Error>(null); <span class="hljs-comment">// rest of component</span> }
Next, we’ll create a function to fetch data from an API, increment the page number, and update the state with the fetched items. Additionally, we’ll handle any errors during the data fetching process:
<span class="hljs-keyword">const</span> fetchData = async (page: <span class="hljs-built_in">number</span>) => { <span class="hljs-keyword">try</span> { setLoading(<span class="hljs-literal">true</span>); <span class="hljs-keyword">const</span> res = await fetch( `https://dummyjson.com/products/?limit=10&skip=${(page - 1) * 10}` ); <span class="hljs-keyword">const</span> data = await res.json(); <span class="hljs-keyword">if</span> (res.ok) { setProducts((prevItems) => [...prevItems, ...data.products]); page === <span class="hljs-number">1</span> && setTotalProducts(() => data.total); <span class="hljs-comment">// only set this once</span> } setLoading(<span class="hljs-literal">false</span>); } <span class="hljs-keyword">catch</span> (error) { setLoading(<span class="hljs-literal">false</span>); <span class="hljs-keyword">if</span> (error <span class="hljs-keyword">instanceof</span> Error) { setError(error); } } };
For this tutorial, we will be using the DummyJSON products API. DummyJSON doesn’t offer an explicit page
param. Instead, it uses limit
and skip
for rendering pagination. limit
is the maximum number of products we want per API call, and skip
is the number of items we intend to skip for each page, which in our case would be the previous page multiplied by 10.
fetchData
on component mountNext, we’ll use the useEffect
Hook to call the fetchData
function when the component mounts initially:
useEffect(() => { let subscribed = <span class="hljs-literal">true</span>; (async () => { if (subscribed) { await fetchData(<span class="hljs-number">1</span>); } })(); return () => { subscribed = <span class="hljs-literal">false</span>; }; }, []);
In a useEffect
hook, we want to make sure we clean up the asynchronous function call to avoid state updates when the component has unmounted. AbortController
is another method of unsubscribing from a fetch call. You can learn more on how to clean up React’s useEffect hook.
ProductCard
componentFinally, we will create the ProductCard
component that would be used for each product and the CSS styles it needs. So go ahead and create a component
directory inside src
. In that, create a ProductCard.tsx
file and paste the code below:
export const ProductCard = ({ product }: { product: ProductItem }) => { const discountedPrice = ( product.price - (product.price * product.discountPercentage) / 100 ).toFixed(<span class="hljs-number">2</span>); return ( <div className="product-card"> <img src={product.thumbnail} alt={product.title} className="product-image" /> <div className="product-info"> <h2 className="product-title"> {product.title} - {product.id} </h2> <span className="product-category">{product.category}</span> {product.brand && ( <span className="product-brand">{product.brand}</span> )} <p className="product-description">{product.description}</p> <div className="product-props"> <div className="product-price"> ${discountedPrice} <span className="product-original-price"> ${product.price.toFixed(<span class="hljs-number">2</span>)} </span> </div> <div className="product-rating"> <span className="star-rating">{"★"}</span> <span>{Math.floor(product.rating)}</span> </div> </div> <button className="add-to-cart">Add to Cart</button> </div> </div> ); };
The Vite template we used in creating the React app comes with two CSS files by default, but we only need one. Delete the App.css
and its import in App.tsx
. In index.css
, replace the styles there with the ones below:
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap"); .App { font-family: "Poppins", sans-serif; } .products-list { display: grid; grid-template-columns: 1fr; grid-gap: 10px; max-width: 768px; margin: 0 auto; } @media screen and (min-width: 768px) { .products-list { grid-template-columns: 1fr 1fr; } } .product-card { background-color: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); max-width: 400px; width: 100%; overflow: hidden; font-family: "Poppins", sans-serif; } .product-image { width: 100%; height: 250px; object-fit: cover; } .product-info { padding: 20px; } .product-title { font-size: 24px; margin: 0 0 10px; } .product-category, .product-brand { display: inline-block; background-color: #e0e0e0; padding: 5px 10px; border-radius: 15px; font-size: 12px; margin-right: 5px; } .product-description { font-size: 14px; color: #666; margin: 10px 0; } .product-props { display: flex; justify-content: space-between; align-items: center; } .product-price { font-size: 24px; font-weight: bold; margin: 10px 0; } .product-original-price { text-decoration: line-through; color: #999; font-size: 16px; margin-left: 10px; } .product-rating { display: flex; align-items: center; margin: 10px 0; } .star-rating { color: #ffd700; font-size: 18px; margin-right: 5px; } .add-to-cart { display: block; width: 100%; padding: 10px; background-color: #4caf50; color: white; border: none; border-radius: 4px; font-size: 16px; cursor: pointer; margin-top: 20px; } .add-to-cart:hover { background-color: #45a049; }
These foundational steps will be present in all the techniques we discuss in this article. We’ll modify and expand upon them as a base.
Building the entire infinite scroll implementation from scratch involves handling the scroll event, loading more data, and updating the state in your React application. This approach provides you with full control over customization and functionality.
To get started, create a component FromScratch.tsx
in the components directory, and initialize:
import { useEffect, useState } from "react"; import { ProductCard } from "./ProductCard"; import { ProductItem } from "../types"; export const FromScratch = ({ products, fetchData, loading, error }: { products: ProductItem[]; fetchData: (page: number) => Promise<void>; loading: boolean; error: null|Error }) => { const [page, setPage] = useState(<span class="hljs-number">1</span>); <span class="hljs-comment">// scroll logic </span> return ( <div> <div className="products-list"> {products.map((product, index) => ( <ProductCard product={product} key={index} /> ))} </div> {loading && <p>Loading...</p>} {error && <p>Error: {error.message}</p>} </div> ); };
Next, we’ll create a function to handle the scroll
event. This function will check if the user has reached the bottom of the page and call fetchData
if necessary. We’ll add a scroll
event listener to the window
object and remove it when the component is unmounted. In place of the // scroll logic
comment, add this:
const handleScroll = () => { const bottom = Math.ceil(window.innerHeight + window.scrollY) >= document.documentElement.scrollHeight - 200; if (bottom) { setPage((prevPage) => { const nextPage = prevPage + 1; fetchData(nextPage); return nextPage; }); } }; useEffect(() => { window.addEventListener("scroll", handleScroll); return () => { window.removeEventListener("scroll", handleScroll); }; }, []);
If you’re wondering why the fetchData
is called inside the setPage
callback, it is simply because the fetchData
function is a side effect of the page
state. With this we’re making sure the fetchData
has access to the most recent page
state.
React’s state updates are asynchronous, so relying on the updated state immediately after calling the setState function can lead to race conditions. Another alternative is to use the useEffect
hook to track when the page
has been updated, but in this case, we don’t have that luxury.
Next, let’s import our newly created component into App.tsx
and run the app:
<span class="hljs-comment">// App.tsx</span> <div> <FromScratch products={products} fetchData={fetchData} loading={loading} error={error} /> </div>
You can run the app with:
npm run dev
And in your browser you should have something like this:
If you’re not creating along with this tutorial, then you can follow up with the Codesandbox app.
Our handleScroll
function performs a check for the bottom of the page every time the user scrolls, which we don’t want. Instead, we only want to check for the bottom when the user stops scrolling. Debouncing in React in our case creates a cooling period where it waits until the user has stopped scrolling before executing our check function:
<span class="hljs-comment">// FromScratch.tsx</span> const debounce = (func: (args: any) => void, delay: number) => { let timeoutId: ReturnType<typeof setTimeout>; return function (...args: any) { if (timeoutId) { clearTimeout(timeoutId); } timeoutId = setTimeout(() => { func(args); }, delay); }; };
Next we’ll update the handleScroll
to make use of the debounce
function:
const handleScroll = debounce(() => { const bottom = Math.ceil(window.innerHeight + window.scrollY) >= document.documentElement.scrollHeight - 200; if (bottom) { setPage((prevPage) => { const nextPage = prevPage + 1; fetchData(nextPage); return nextPage; }); } }, 300);
The purpose of clearing the timeout in the debounce function is to cancel previous timeouts when scrolling resumes.
In a full-scale application, you’d most likely need infinite scroll in multiple pages; in this section we’ll make the scroll function a reusable custom hook. So create a hooks
directory in src
and create a useInfiniteScroll.ts
file:
import { useEffect, useState } from "react"; const debounce = (func: (args: any) => void, delay: number) => { let timeoutId: ReturnType<typeof setTimeout>; return function (...args: any) { if (timeoutId) { clearTimeout(timeoutId); } timeoutId = setTimeout(() => { func(args); }, delay); }; }; export const useInfiniteScroll = (fetchData: (page: number) => Promise<void>) => { const [page, setPage] = useState(<span class="hljs-number">1</span>); const handleScroll = debounce(() => { const bottom = Math.ceil(window.innerHeight + window.scrollY) >= document.documentElement.scrollHeight - 200; if (bottom) { setPage((prevPage) => { const nextPage = prevPage + 1; fetchData(nextPage); return nextPage; }); } }, 300); useEffect(() => { window.addEventListener("scroll", handleScroll); return () => { window.removeEventListener("scroll", handleScroll); }; }, []); };
Now in FromScratch.tsx
we can replace the scroll logic with:
export const FromScratch = ({ products, fetchData, loading, error, }: { products: ProductItem[]; fetchData: (page: number) => Promise<void>; loading: boolean; error: null | Error; }) => { useInfiniteScroll(fetchData); <span class="hljs-comment">// rest of component</span> };
With that, we have a fully functional infinite scroll implementation built from scratch. This approach allows for extensive customization and more control over functionality. However, it may be more time-consuming and, as we’ve seen, requires more maintenance than using an existing library or component.
Using an existing infinite scroll library or component can save time and effort as you leverage pre-built and pre-tested solutions while retaining customization options. We will cover two of these libraries in this section.
react-infinite-scroll-component is a popular library for implementing infinite scrolling in React. Let’s learn how to use this library to create infinite scrolling in our e-commerce application. First, install react-infinite-scroll-component:
npm install react-infinite-scroll-component
Now we can create a new component within the components
directory, we’ll call it WithReactScroll.tsx
. We’ll import the InfiniteScroll
component from the library, and wrap the list of products in it. Configure the component by passing the necessary props like dataLength
, next
, hasMore
, and loader
:
import InfiniteScroll from "react-infinite-scroll-component"; import { ProductCard } from "./ProductCard"; import { useState } from "react"; export const WithReactScroll = ({ products, fetchData, totalProducts, }: { products: ProductItem[]; fetchData: (page: number) => Promise<void>; totalProducts: number; }) => { const [page, setPage] = useState(<span class="hljs-number">1</span>); const handleLoadMoreData = () => { setPage((prevPage) => { const nextPage = prevPage + 1; fetchData(nextPage); return nextPage; }); }; return ( <InfiniteScroll dataLength={products.length} next={handleLoadMoreData} hasMore={totalProducts > products.length} loader={<p>Loading...</p>} endMessage={<p>No more data to load.</p>} > <div className="products-list"> {products.map((item) => ( <ProductCard product={item} key={item.id} /> ))} </div> </InfiniteScroll> ); };
Now we can import the WithReactScroll
component into our App
component to see the result:
<div> <WithReactScroll products={products} fetchData={fetchData} totalProducts={totalProducts} /> </div>
You can view the result on Codesandbox.
With that, we’ve implemented infinite scrolling in our React application. We didn’t use the window’s scroll
event because react-infinite-scroll-component
handles that for us. The react-infinite-scroll-component
library offers a faster and more streamlined implementation process but still provides customization options, like scroll height and scroll overflow. However, you should keep in mind the trade-off of introducing additional dependencies to your project.
Second on our list is the react-window library, which was designed for rendering large lists efficiently, and the react-window-infinite-loader library, which is used to handle infinite scrolling and load more data as the user scrolls. First, we’ll install the react-window-infinite-loader and react-window library:
npm install react-window-infinite-loader react-window
Next, we’ll create a WithReactWindow
component in the components
directory:
import { useState } from "react"; import { FixedSizeList as List } from "react-window"; import InfiniteLoader from "react-window-infinite-loader"; import { ProductCard } from "./ProductCard"; export const WithReactWindow = ({ fetchData, products, totalProducts, loading, }: { products: ProductItem[]; fetchData: (page: number) => Promise<void>; totalProducts: number; loading: boolean; }) => { const [page, setPage] = useState(<span class="hljs-number">1</span>); const hasNextPage = totalProducts > products.length; const handleLoadMoreData = () => { if (loading) return; setPage((prevPage) => { const nextPage = prevPage + 1; fetchData(nextPage); return nextPage; }); }; const isItemLoaded = (index: number) => !hasNextPage || index < products.length; const Row = ({ index, style }: { index: number, style: { [key:string]:any } }) => { return ( <div style={style}> {isItemLoaded(index) ? ( <ProductCard product={products[index]} /> ) : ( "Loading..." )} </div> ); }; return ( <InfiniteLoader isItemLoaded={isItemLoaded} itemCount={hasNextPage ? products.length + 1 : products.length} loadMoreItems={handleLoadMoreData} > {({ onItemsRendered, ref }) => ( <List height={window.innerHeight} itemCount={products.length} itemSize={600} onItemsRendered={onItemsRendered} ref={ref} width={450} > {Row} </List> )} </InfiniteLoader> ); };
In the code above, when we combine InfiniteLoader()
and FixedSizeList()
, the component ensures that only the visible items are rendered and new items are loaded as the user scrolls downwards continuously, creating the infinite scroll feature.
Now we can import the component into App
to see the result:
<div> <WithReactWindow products={products} fetchData={fetchData} totalProducts={totalProducts} loading={loading} /> </div>
You can also view the result on Codesandbox.
The Intersection Observer API is a modern development technique that can detect when elements come into view, thereby triggering content loading for infinite scrolling. The Intersection Observer API observes changes in the intersection of target elements with an ancestor element or the viewport, making it well-suited to implement infinite scrolling.
We’ll create a new component inside the components
directory, we can call it WithIntersectionObserver
. Next, we’ll create a ref
for the observer
target element and set up the Intersection Observer in a useEffect
Hook. When the target element comes into view, call the fetchData
function as follows:
import { useEffect, useRef, useState } from "react"; import { ProductCard } from "./ProductCard"; export const WithIntersectionObserver = ({ products, fetchData, error, loading }: { products: ProductItem[]; fetchData: (page: number) => Promise<void>; error: null|Error, loading: boolean }) => { const [page, setPage] = useState(<span class="hljs-number">1</span>); const observerTarget = useRef(null); useEffect(() => { const observer = new IntersectionObserver( (entries) => { if (entries[0].isIntersecting) { setPage((prevPage) => { const nextPage = prevPage + 1; fetchData(nextPage); return nextPage; }); } }, { threshold: 1 } ); if (observerTarget.current) { observer.observe(observerTarget.current); } return () => { if (observerTarget.current) { observer.unobserve(observerTarget.current); } }; }, [observerTarget]); <span class="hljs-comment">// rest of component</span> };
Then, render the items, loading indicator, error messages, and the observer
target element within the component:
return ( <> <div className="products-list"> {products.map((product) => ( <ProductCard product={product} key={product.id} /> ))} </div> <div ref={observerTarget}></div> {loading && <p>Loading...</p>} {error && <p>Error: {error.message}</p>} </> );
By leveraging the Intersection Observer API, we have created an efficient and performant infinite scrolling solution in our React application. This approach offers a modern, browser-native method for detecting when elements come into view, but it may not be supported in old browsers and environments without using a polyfill.
Next, we’ll import the new component into App
to see the results:
<span class="hljs-comment">//App.tsx</span> <div> <WithIntersectionObserver products={products} fetchData={fetchData} loading={loading} error={error} /> </div>
You can also view the results on Codesandbox.
We’ve explored three different ways to implement infinite scroll in React. Since you’ll likely only need one for your application, choosing the right method depends on your app’s specific requirements. Here are some key considerations to help you decide:
Let’s break down the pros and cons of each method:
This approach gives you full control over the implementation and allows for unlimited customization. However, it requires more effort to optimize performance (e.g., debouncing scroll events, efficiently updating the DOM) and can be prone to bugs if not implemented carefully.
Use this method if:
Libraries provide a quick and reliable way to implement infinite scroll, often with built-in optimizations and community support. However, they can add bloat to your app, and you’ll rely on the library’s maintainers for updates and bug fixes.
Use this method if:
This modern approach eliminates the need for scroll event listeners and debouncing, making it more performant and easier to maintain. However, it’s not fully supported in older browsers like Internet Explorer.
Use this method if:
ref
and scrollTop
APIScroll to top is an additional functionality often implemented in infinite scrolling that provides a better user experience. If you’ve been on social media anytime recently, you’re familiar with scroll to top.
In X, for example, when you scroll through your for you page (FYP), it never really ends; this is an example of infinite scrolling in action. Then, when you click the home icon in the X navigation menu, it takes you right back to the top. The home icon in X serves two purposes: to refresh and fetch more data from your FYP and to provide modern scroll to top functionality.
For a good user experience, I think all implementations of infinite scroll should have the option to scroll back up to the top of the feed. To implement this in React, we will need the scrollTop()
property and the useRef()
Hook to have good control of the scroll position.
Both of them are a strong mix that comes in handy when implementing features like the scroll to top buttons or dynamically loading content as the user scrolls, as seen in the example where we built the entire implementation from scratch. We will implement it in our App.tsx
file:
import React, { useRef } from 'react'; function App() { const scrollableDiv = useRef<HTMLDivElement | null>(null); <span class="hljs-comment">// scroll logic</span> const scrollToTop = () => { if (scrollableDiv.current) { scrollableDiv.current.scrollTop = 0; } }; return ( <div ref={scrollableDiv}> <!-- Infinite Scroll content --> <button onClick={scrollToTop}>Scroll to Top</button> </div> ); } export default ScrollableComponent;
In the code above, the scroll to the top is achieved using a ref
and scrollTop()
, which directly accesses and manipulates the scroll position of the div
through the scrollToTop()
function. With this, we can easily improve our user’s infinite scrolling experience.
Infinite scrolling is a powerful web design technique. It enhances the user experience by progressively loading content as users scroll down a page, thereby eliminating the need for pagination. In this article, we explored four different approaches for implementing infinite scrolling in React applications by building an e-commerce products page.
Each technique has its advantages and potential drawbacks, so it’s essential to choose the method that best suits your specific requirements and your users’ needs. By implementing infinite scrolling in your React applications, you can provide an intuitive and engaging user experience that keeps visitors engaged with your content. I hope you enjoyed this article! Be sure to leave a comment if you have any questions.
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowLearn how the call stack, event loop, and various queues help JavaScript handle asynchronous operations while maintaining its single-threaded nature.
Arrow functions have a simpler syntax than standard functions, and there are some important differences in how they behave.
null
, undefined
, or empty values in JavaScriptIn most languages, we only have to cater to null. But in JavaScript, we have to cater to both null and undefined. How do we do that?
Discover how the MERN stack (MongoDB, Express.js, React, Node.js) enables developers to build dynamic, performant, modern websites and apps.
2 Replies to "3 ways to implement infinite scroll in React (with code examples)"
Hi,
Thanks,
I followed you & implemented the infinite scroll. I have been facing this issue.
I have set page size 30, So for each API response I receive the 30 data. The problem is, when I open the application in big screen like TV/projector, Initial API call loads the 30 data & no scroll appear due to large screen. But I have 1000 data in Database.
I told team, We could increase the initial page size 100, then they asked suppose after increased size What If the scroll doesn’t appear on window. More over, they want to keep page size 30 only, do not want to change.
How to solve when I open the application in big screen, load the data until scroll appear?
This error occured because you did not specify the context in which the infinite scroll should work. It defaults to the viewport if not set.
The solution is that you pass in the root which is a selector to the options object as shown below.
let options = {
root: document.querySelector(“#scrollArea”),
rootMargin: “0px”,
threshold: 1.0,
};
let observer = new IntersectionObserver(callback, options);