{"id":2398,"date":"2025-06-25T04:14:24","date_gmt":"2025-06-25T04:14:24","guid":{"rendered":"https:\/\/200oksolutions.com\/blog\/?p=2398"},"modified":"2026-10-23T05:22:58","modified_gmt":"2026-10-23T05:22:58","slug":"infinite-scroll-react-using-react-infinite-scroll-component","status":"publish","type":"post","link":"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component\/","title":{"rendered":"Infinite Scroll in React with a Real API Example"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Infinite scroll in React loads the next batch of data as the user nears the end of a list, so there is no \u201cNext page\u201d button to click. You can build it three ways: a custom Intersection Observer hook, the react-infinite-scroll-component library, or TanStack Query\u2019s <code>useInfiniteQuery<\/code>. This guide builds all three against a real API, compares them, and covers the SEO, accessibility and performance traps most tutorials skip.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Which infinite scroll method should you use?<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Method<\/th><th>Best for<\/th><th>Extra dependency<\/th><th>Caching and retries<\/th><th>Effort<\/th><\/tr><tr><td>Intersection Observer hook<\/td><td>Full control and the smallest bundle<\/td><td>None<\/td><td>You write it<\/td><td>Medium<\/td><\/tr><tr><td>react-infinite-scroll-component<\/td><td>A quick setup on a simple list<\/td><td>react-infinite-scroll-component<\/td><td>You write it<\/td><td>Low<\/td><\/tr><tr><td>TanStack Query + Intersection Observer<\/td><td>Production apps with server data<\/td><td>@tanstack\/<br>react-query<\/td><td>Built in<\/td><td>Medium<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">As a rule of thumb, use the custom hook when you want zero dependencies, the library when you need a working list in ten minutes, and TanStack Query when the data comes from a real backend and you care about caching, retries and race conditions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What is infinite scroll in React?<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Infinite scroll is a loading pattern where new items are appended to a list automatically as the user scrolls. Under the hood, every implementation has the same three parts:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>A trigger<\/strong> that detects when the user is close to the end of the list.<\/li>\n\n\n\n<li><strong>A fetch<\/strong> that requests the next page, using an offset (<code>limit<\/code> and <code>skip<\/code>) or a cursor.<\/li>\n\n\n\n<li><strong>An append<\/strong> that adds the new items to state without replacing the old ones.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The examples below use the free DummyJSON products API. A request like <code>https:\/\/dummyjson.com\/products?limit=10&amp;skip=0<\/code> returns <code>products<\/code>, <code>total<\/code>, <code>skip<\/code> and <code>limit<\/code>, which is everything we need.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Set up the project<\/strong><\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>npm create vite@latest infinite-scroll-app -- --template react\ncd infinite-scroll-app\nnpm install<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Method 1: Infinite scroll with Intersection Observer (custom hook)<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Scroll event listeners fire constantly and need throttling. The Intersection Observer API is cheaper: the browser tells you only when a target element enters the viewport. We place a tiny invisible \u201csentinel\u201d element after the list and load more whenever it becomes visible.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, a reusable hook:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ useInfiniteScroll.js\nimport { useEffect, useRef } from 'react';\n\nexport function useInfiniteScroll(onLoadMore, { enabled = true, rootMargin = '200px' } = {}) {\n  const sentinelRef = useRef(null);\n  const onLoadMoreRef = useRef(onLoadMore);\n  onLoadMoreRef.current = onLoadMore; \/\/ always call the latest callback\n\n  useEffect(() =&gt; {\n    const node = sentinelRef.current;\n    if (!enabled || !node) return;\n\n    const observer = new IntersectionObserver(\n      (&#91;entry]) =&gt; {\n        if (entry.isIntersecting) onLoadMoreRef.current();\n      },\n      { rootMargin }\n    );\n\n    observer.observe(node);\n    return () =&gt; observer.disconnect();\n  }, &#91;enabled, rootMargin]);\n\n  return sentinelRef;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then the component that uses it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ ProductFeed.jsx\nimport { useCallback, useRef, useState } from 'react';\nimport { useInfiniteScroll } from '.\/useInfiniteScroll';\n\nconst LIMIT = 10;\n\nexport default function ProductFeed() {\n  const &#91;products, setProducts] = useState(&#91;]);\n  const &#91;total, setTotal] = useState(null);\n  const &#91;loading, setLoading] = useState(false);\n  const &#91;error, setError] = useState(null);\n  const fetching = useRef(false);\n\n  const hasMore = total === null || products.length &lt; total;\n\n  const loadMore = useCallback(async () =&gt; {\n    if (fetching.current) return; \/\/ blocks duplicate requests\n    fetching.current = true;\n    setLoading(true);\n    setError(null);\n\n    try {\n      const res = await fetch(\n        `https:\/\/dummyjson.com\/products?limit=${LIMIT}&amp;skip=${products.length}`\n      );\n      if (!res.ok) throw new Error(`Request failed with status ${res.status}`);\n      const data = await res.json();\n      setProducts((prev) =&gt; &#91;...prev, ...data.products]);\n      setTotal(data.total);\n    } catch (err) {\n      setError(err.message);\n    } finally {\n      fetching.current = false;\n      setLoading(false);\n    }\n  }, &#91;products.length]);\n\n  const sentinelRef = useInfiniteScroll(loadMore, {\n    enabled: hasMore &amp;&amp; !loading &amp;&amp; !error,\n  });\n\n  return (\n    &lt;section&gt;\n      &lt;h1&gt;Products&lt;\/h1&gt;\n      &lt;ul&gt;\n        {products.map((product) =&gt; (\n          &lt;li key={product.id}&gt;\n            &lt;h2&gt;{product.title}&lt;\/h2&gt;\n            &lt;p&gt;{product.description}&lt;\/p&gt;\n            &lt;strong&gt;${product.price}&lt;\/strong&gt;\n          &lt;\/li&gt;\n        ))}\n      &lt;\/ul&gt;\n\n      {loading &amp;&amp; &lt;p role='status'&gt;Loading more products\u2026&lt;\/p&gt;}\n      {error &amp;&amp; &lt;button onClick={loadMore}&gt;Retry&lt;\/button&gt;}\n      {hasMore &amp;&amp; &lt;div ref={sentinelRef} aria-hidden='true' style={{ height: 1 }} \/&gt;}\n      {!hasMore &amp;&amp; &lt;p&gt;You\u2019ve reached the end.&lt;\/p&gt;}\n    &lt;\/section&gt;\n  );\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>How it works<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The sentinel <code>div<\/code> sits below the list. When it comes within 200px of the viewport (<code>rootMargin<\/code>), the observer calls <code>loadMore<\/code>.<\/li>\n\n\n\n<li>The <code>enabled<\/code> flag turns the observer off while a request is running. When loading finishes, the observer is recreated and fires again if the sentinel is still visible, so short first pages keep loading until the screen is full.<\/li>\n\n\n\n<li>The <code>fetching<\/code> ref blocks duplicate requests, including the double effect run you get in React StrictMode during development.<\/li>\n\n\n\n<li><code>skip<\/code> comes from <code>products.length<\/code>, so the offset can never drift out of sync with the list.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Method 2: Infinite scroll with react-infinite-scroll-component<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">react-infinite-scroll-component wraps the scroll detection for you. It is the fastest route to a working list.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install react-infinite-scroll-component<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ ProductList.jsx\nimport { useEffect, useRef, useState } from 'react';\nimport InfiniteScroll from 'react-infinite-scroll-component';\n\nconst LIMIT = 10;\n\nexport default function ProductList() {\n  const &#91;products, setProducts] = useState(&#91;]);\n  const &#91;total, setTotal] = useState(null);\n  const fetching = useRef(false);\n\n  const fetchMore = async () =&gt; {\n    if (fetching.current) return;\n    fetching.current = true;\n    try {\n      const res = await fetch(\n        `https:\/\/dummyjson.com\/products?limit=${LIMIT}&amp;skip=${products.length}`\n      );\n      const data = await res.json();\n      setProducts((prev) =&gt; &#91;...prev, ...data.products]);\n      setTotal(data.total);\n    } catch (err) {\n      console.error('Could not load products', err);\n    } finally {\n      fetching.current = false;\n    }\n  };\n\n  useEffect(() =&gt; {\n    fetchMore();\n  }, &#91;]);\n\n  return (\n    &lt;InfiniteScroll\n      dataLength={products.length}\n      next={fetchMore}\n      hasMore={total === null || products.length &lt; total}\n      loader={&lt;p role='status'&gt;Loading more products\u2026&lt;\/p&gt;}\n      endMessage={&lt;p&gt;You\u2019ve reached the end.&lt;\/p&gt;}\n    &gt;\n      {products.map((product) =&gt; (\n        &lt;article key={product.id}&gt;\n          &lt;h2&gt;{product.title}&lt;\/h2&gt;\n          &lt;p&gt;{product.description}&lt;\/p&gt;\n          &lt;strong&gt;${product.price}&lt;\/strong&gt;\n        &lt;\/article&gt;\n      ))}\n    &lt;\/InfiniteScroll&gt;\n  );\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The props that matter:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>dataLength<\/code> tells the component how many items are rendered, so it knows when new data has arrived.<\/li>\n\n\n\n<li><code>next<\/code> is called when the user scrolls near the bottom.<\/li>\n\n\n\n<li><code>hasMore<\/code> stops further calls once everything is loaded.<\/li>\n\n\n\n<li><code>scrollThreshold<\/code> controls how early <code>next<\/code> fires, and <code>scrollableTarget<\/code> lets you scroll inside a fixed-height container instead of the window.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The trade-off: the library only detects scrolling. Caching, retries and race conditions are still your job, which is where Method 3 helps.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Method 3: Infinite scroll with TanStack Query (useInfiniteQuery)<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once data comes from a real backend, hand-written fetch logic gets fragile. TanStack Query\u2019s infinite queries track pages, <code>hasNextPage<\/code>, loading state, caching, retries and request deduplication for you. We keep the Intersection Observer hook from Method 1 as the trigger.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install @tanstack\/react-query<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Wrap your app once:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ main.jsx\nimport { QueryClient, QueryClientProvider } from '@tanstack\/react-query';\n\nconst queryClient = new QueryClient();\n\nReactDOM.createRoot(document.getElementById('root')).render(\n  &lt;QueryClientProvider client={queryClient}&gt;\n    &lt;App \/&gt;\n  &lt;\/QueryClientProvider&gt;\n);<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then build the feed:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ QueryProductFeed.jsx\nimport { useInfiniteQuery } from '@tanstack\/react-query';\nimport { useInfiniteScroll } from '.\/useInfiniteScroll';\n\nconst LIMIT = 10;\n\nasync function fetchProducts({ pageParam }) {\n  const res = await fetch(\n    `https:\/\/dummyjson.com\/products?limit=${LIMIT}&amp;skip=${pageParam}`\n  );\n  if (!res.ok) throw new Error('Failed to fetch products');\n  return res.json();\n}\n\nexport default function QueryProductFeed() {\n  const { data, fetchNextPage, hasNextPage, isFetchingNextPage, status, error } =\n    useInfiniteQuery({\n      queryKey: &#91;'products'],\n      queryFn: fetchProducts,\n      initialPageParam: 0,\n      getNextPageParam: (lastPage) =&gt; {\n        const next = lastPage.skip + lastPage.limit;\n        return next &lt; lastPage.total ? next : undefined; \/\/ undefined = no more pages\n      },\n    });\n\n  const sentinelRef = useInfiniteScroll(fetchNextPage, {\n    enabled: Boolean(hasNextPage) &amp;&amp; !isFetchingNextPage,\n  });\n\n  if (status === 'pending') return &lt;p role='status'&gt;Loading\u2026&lt;\/p&gt;;\n  if (status === 'error') return &lt;p&gt;Something went wrong: {error.message}&lt;\/p&gt;;\n\n  const products = data.pages.flatMap((page) =&gt; page.products);\n\n  return (\n    &lt;section&gt;\n      &lt;ul&gt;\n        {products.map((product) =&gt; (\n          &lt;li key={product.id}&gt;{product.title}&lt;\/li&gt;\n        ))}\n      &lt;\/ul&gt;\n      {isFetchingNextPage &amp;&amp; &lt;p role='status'&gt;Loading more\u2026&lt;\/p&gt;}\n      {hasNextPage &amp;&amp; &lt;div ref={sentinelRef} aria-hidden='true' style={{ height: 1 }} \/&gt;}\n    &lt;\/section&gt;\n  );\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">What you get for free: returning <code>undefined<\/code> from <code>getNextPageParam<\/code> ends the feed, <code>data.pages<\/code> holds every page loaded so far, a failed request retries automatically, and navigating away and back shows cached pages instantly instead of refetching from page one.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Infinite scroll for large lists: add virtualization<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Appending items forever means the DOM grows forever. After a few thousand rows, scrolling slows down and memory climbs. The fix is windowing (virtualization), which renders only the rows currently on screen. Libraries such as react-window and TanStack Virtual do this, and react-window-infinite-loader pairs windowing with page loading. If your list can realistically pass a few hundred items, plan for virtualization from the start.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Infinite scroll vs pagination vs load more button<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Pattern<\/th><th>Best for<\/th><th>Watch out for<\/th><\/tr><tr><td>Infinite scroll<\/td><td>Feeds, discovery browsing, image galleries<\/td><td>Unreachable footer, no shareable position, harder to index<\/td><\/tr><tr><td>Pagination<\/td><td>Search results, catalogues, anything users bookmark<\/td><td>More clicks and page loads<\/td><\/tr><tr><td>Load more button<\/td><td>A middle ground for most product lists<\/td><td>One extra click per batch<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">A \u201cLoad more\u201d button is often the best default. Users stay in control, the footer stays reachable, and keyboard and screen reader users are not fighting an endless list.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>SEO and accessibility checklist<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Make content crawlable.<\/strong> Search engines do not scroll. Back your feed with real paginated URLs (for example <code>\/products?page=2<\/code>) linked with ordinary <code>&lt;a href><\/code> tags, and update the URL with the History API as pages load.<\/li>\n\n\n\n<li><strong>Render the first page on the server.<\/strong> Frameworks such as Next.js can send page one as HTML so crawlers and slow devices see content immediately.<\/li>\n\n\n\n<li><strong>Keep the footer reachable.<\/strong> Use a Load more button, or stop auto-loading after a set number of pages.<\/li>\n\n\n\n<li><strong>Announce loading.<\/strong> Use <code>role='status'<\/code> or <code>aria-live='polite'<\/code> on the loader so screen readers hear that new items arrived.<\/li>\n\n\n\n<li><strong>Never steal focus.<\/strong> Append new items after the current focus position and keep keyboard order logical.<\/li>\n\n\n\n<li><strong>Respect <code>prefers-reduced-motion<\/code>.<\/strong> Skip fade-in and skeleton animations for users who ask for less motion.<\/li>\n\n\n\n<li><strong>Restore scroll position.<\/strong> When users return from a detail page, bring back the same items and position.<\/li>\n\n\n\n<li><strong>Handle errors and empty states.<\/strong> Always show a retry option and a clear end-of-list message.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Common infinite scroll mistakes in React<\/strong><\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Double fetching in StrictMode.<\/strong> In development, React runs effects twice. Guard requests with a ref (as above) or let TanStack Query deduplicate them.<\/li>\n\n\n\n<li><strong>Stale closures.<\/strong> Reading state inside an async callback gives you old values. Use functional updates (<code>setProducts(prev => ...)<\/code>) and derive the offset from the current list.<\/li>\n\n\n\n<li><strong>Missing or duplicate keys.<\/strong> Use a stable ID such as <code>product.id<\/code>, never the array index.<\/li>\n\n\n\n<li><strong>No end condition.<\/strong> Compare loaded items to <code>total<\/code>, or stop when the API returns an empty page.<\/li>\n\n\n\n<li><strong>Unbounded list growth.<\/strong> Virtualize or cap the list so memory stays flat.<\/li>\n\n\n\n<li><strong>No error state.<\/strong> A silent failure leaves users staring at a spinner. Show the error and a Retry button.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Infinite scroll in React Native<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">React Native has this built in. <code>FlatList<\/code> calls <code>onEndReached<\/code> when the user scrolls within <code>onEndReachedThreshold<\/code> of the end of the list. Use the same pagination logic and the same guard against duplicate requests shown above.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Q. How do I implement infinite scroll in React?<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>A.<\/strong> Keep the loaded items in state, place a sentinel element below the list, and use an Intersection Observer to call your fetch function when the sentinel becomes visible. Append the new items with a functional state update and stop when the API says there is no more data.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Q. Is Intersection Observer better than a scroll event listener?<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>A.<\/strong> For infinite scroll, yes. A scroll listener runs on every scroll event and usually needs throttling. Intersection Observer notifies you only when the target enters the viewport, which is simpler and lighter on the main thread.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Q. Is infinite scroll bad for SEO?<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>A.<\/strong> It can be, if content only loads when a user scrolls. Search engine crawlers do not scroll, so items beyond the first batch may never be discovered. Add paginated URLs with normal links behind the feed, and server-render the first page.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Q. What is the difference between react-infinite-scroll-component and TanStack Query?<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>A.<\/strong> They solve different problems. react-infinite-scroll-component detects scrolling and triggers a load. TanStack Query manages fetching, caching, retries and pagination state. Many production apps use a scroll trigger together with <code>useInfiniteQuery<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Q. How do I handle thousands of items in an infinite list?<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>A. <\/strong>Use virtualization. Libraries like react-window or TanStack Virtual render only the visible rows, which keeps the DOM small and scrolling smooth however many items you have loaded.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For a small project, the custom Intersection Observer hook gives you control with no dependencies &amp; quickest start, react-infinite-scroll-component works well. For real applications with server data, pair the observer with TanStack Query\u2019s <code>useInfiniteQuery<\/code>, and add virtualization once lists grow long. Whichever you choose, give search engines paginated URLs and give users a way to reach the footer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Building a React product where performance, data loading and user experience all matter? 200OK Solutions provides <a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/www.200oksolutions.com\/services\/product-development\/\">digital product development<\/a> services, from frontend architecture and API integration to launch. <a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/www.200oksolutions.com\/contact\/\">Contact us<\/a> to talk through your project, or read our series on <a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/www.200oksolutions.com\/blog\/react-19-new-features-future-development-part-3-final\/\">what\u2019s new in React 19<\/a> to keep your stack current.<\/p>\n\n\n<div class=\"is-default-size wp-block-site-logo\"><a href=\"https:\/\/www.200oksolutions.com\/blog\/\" class=\"custom-logo-link light-mode-logo\" rel=\"home\"><img fetchpriority=\"high\" decoding=\"async\" width=\"484\" height=\"191\" src=\"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2026\/01\/cropped-200ok_logo.png\" class=\"custom-logo\" alt=\"200OK Solutions Blog\" srcset=\"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2026\/01\/cropped-200ok_logo.png 484w, https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2026\/01\/cropped-200ok_logo-300x118.png 300w\" sizes=\"(max-width: 484px) 100vw, 484px\" \/><\/a><\/div>","protected":false},"excerpt":{"rendered":"<p>Infinite scroll in React loads the next batch of data as the user nears the&hellip;<\/p>\n","protected":false},"author":5,"featured_media":5308,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1088],"tags":[392,630,1033,1084,1064,1063,1086,1083,1085,1087,207],"class_list":["post-2398","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-react","tag-200ok-solutions","tag-api-integration","tag-frontend-development","tag-infinite-scroll","tag-infinite-scroll-component-react","tag-infinite-scroll-in-react","tag-javascript","tag-react","tag-react-infinite-scroll-component","tag-ux-ui","tag-web-development"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Infinite scroll in React with a real API example for web development<\/title>\n<meta name=\"description\" content=\"Learn infinite scroll in React three ways: React-infinite-scroll-component and TanStack Query. Code, comparison and SEO tips.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Infinite scroll in React with a real API example for web development\" \/>\n<meta property=\"og:description\" content=\"Learn infinite scroll in React three ways: React-infinite-scroll-component and TanStack Query. Code, comparison and SEO tips.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component\/\" \/>\n<meta property=\"og:site_name\" content=\"200OK Solutions Blog\" \/>\n<meta property=\"article:published_time\" content=\"2025-06-25T04:14:24+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-23T05:22:58+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2025\/06\/How-to-Migrate-to-Cloud-Native-Architectures-Using-Microservices-1-2026-10-23T104417.512.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2240\" \/>\n\t<meta property=\"og:image:height\" content=\"1260\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Piyush Solanki\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Piyush Solanki\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component\/\"},\"author\":{\"name\":\"Piyush Solanki\",\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/#\/schema\/person\/e07f6b8e3c9a90ce7b3b09427d26155e\"},\"headline\":\"Infinite Scroll in React with a Real API Example\",\"datePublished\":\"2025-06-25T04:14:24+00:00\",\"dateModified\":\"2026-10-23T05:22:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component\/\"},\"wordCount\":1420,\"publisher\":{\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2025\/06\/How-to-Migrate-to-Cloud-Native-Architectures-Using-Microservices-1-2026-10-23T104417.512.png\",\"keywords\":[\"200OK Solutions\",\"API Integration\",\"Frontend development\",\"Infinite Scroll\",\"Infinite scroll component React\",\"Infinite Scroll in React\",\"JavaScript\",\"React\",\"React Infinite Scroll Component\",\"UX\/UI\",\"Web Development\"],\"articleSection\":[\"React\"],\"inLanguage\":\"en-US\"},{\"@type\":[\"WebPage\",\"SearchResultsPage\"],\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component\/\",\"url\":\"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component\",\"name\":\"Infinite scroll in React with a real API example for web development\",\"isPartOf\":{\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2025\/06\/How-to-Migrate-to-Cloud-Native-Architectures-Using-Microservices-1-2026-10-23T104417.512.png\",\"datePublished\":\"2025-06-25T04:14:24+00:00\",\"dateModified\":\"2026-10-23T05:22:58+00:00\",\"description\":\"Learn infinite scroll in React three ways: React-infinite-scroll-component and TanStack Query. Code, comparison and SEO tips.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component#primaryimage\",\"url\":\"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2025\/06\/How-to-Migrate-to-Cloud-Native-Architectures-Using-Microservices-1-2026-10-23T104417.512.png\",\"contentUrl\":\"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2025\/06\/How-to-Migrate-to-Cloud-Native-Architectures-Using-Microservices-1-2026-10-23T104417.512.png\",\"width\":2240,\"height\":1260,\"caption\":\"Infinite scroll in React with a real API example for web development | 200OK Solutions\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.200oksolutions.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Blog >React > Infinite Scroll in React with a Real API Example\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/#website\",\"url\":\"https:\/\/www.200oksolutions.com\/blog\/\",\"name\":\"Web Development, Software, and App Blog | 200OK Solutions\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.200oksolutions.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/#organization\",\"name\":\"200OK Solutions\",\"url\":\"https:\/\/www.200oksolutions.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2025\/09\/200ok_logo-CGzMrWDu.png\",\"contentUrl\":\"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2025\/09\/200ok_logo-CGzMrWDu.png\",\"width\":500,\"height\":191,\"caption\":\"200OK Solutions\"},\"image\":{\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.instagram.com\/200ok_solutions\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/#\/schema\/person\/e07f6b8e3c9a90ce7b3b09427d26155e\",\"name\":\"Piyush Solanki\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.200oksolutions.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2026\/05\/cropped-piyush-solanki-96x96.jpg\",\"contentUrl\":\"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2026\/05\/cropped-piyush-solanki-96x96.jpg\",\"caption\":\"Piyush Solanki\"},\"description\":\"Piyush is a seasoned PHP Tech Lead with 10+ years of experience architecting and delivering scalable web and mobile backend solutions for global brands and fast-growing SMEs. He specializes in PHP, MySQL, CodeIgniter, WordPress, and custom API development, helping businesses modernize legacy systems and launch secure, high-performance digital products. He collaborates closely with mobile teams building Android &amp; iOS apps , developing RESTful APIs, cloud integrations, and secure payment systems using platforms like Stripe, AWS S3, and OTP\/SMS gateways. His work extends across CMS customization, microservices-ready backend architectures, and smooth product deployments across Linux and cloud-based environments. Piyush also has a strong understanding of modern front-end technologies such as React and TypeScript, enabling him to contribute to full-stack development workflows and advanced admin panels. With a successful delivery track record in the UK market and experience building digital products for sectors like finance, hospitality, retail, consulting, and food services, Piyush is passionate about helping SMEs scale technology teams, improve operational efficiency, and accelerate innovation through backend excellence and digital tools.\",\"url\":\"https:\/\/www.200oksolutions.com\/blog\/author\/piyush\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Infinite scroll in React with a real API example for web development","description":"Learn infinite scroll in React three ways: React-infinite-scroll-component and TanStack Query. Code, comparison and SEO tips.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component\/","og_locale":"en_US","og_type":"article","og_title":"Infinite scroll in React with a real API example for web development","og_description":"Learn infinite scroll in React three ways: React-infinite-scroll-component and TanStack Query. Code, comparison and SEO tips.","og_url":"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component\/","og_site_name":"200OK Solutions Blog","article_published_time":"2025-06-25T04:14:24+00:00","article_modified_time":"2026-10-23T05:22:58+00:00","og_image":[{"width":2240,"height":1260,"url":"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2025\/06\/How-to-Migrate-to-Cloud-Native-Architectures-Using-Microservices-1-2026-10-23T104417.512.png","type":"image\/png"}],"author":"Piyush Solanki","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Piyush Solanki","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component#article","isPartOf":{"@id":"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component\/"},"author":{"name":"Piyush Solanki","@id":"https:\/\/www.200oksolutions.com\/blog\/#\/schema\/person\/e07f6b8e3c9a90ce7b3b09427d26155e"},"headline":"Infinite Scroll in React with a Real API Example","datePublished":"2025-06-25T04:14:24+00:00","dateModified":"2026-10-23T05:22:58+00:00","mainEntityOfPage":{"@id":"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component\/"},"wordCount":1420,"publisher":{"@id":"https:\/\/www.200oksolutions.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component#primaryimage"},"thumbnailUrl":"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2025\/06\/How-to-Migrate-to-Cloud-Native-Architectures-Using-Microservices-1-2026-10-23T104417.512.png","keywords":["200OK Solutions","API Integration","Frontend development","Infinite Scroll","Infinite scroll component React","Infinite Scroll in React","JavaScript","React","React Infinite Scroll Component","UX\/UI","Web Development"],"articleSection":["React"],"inLanguage":"en-US"},{"@type":["WebPage","SearchResultsPage"],"@id":"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component\/","url":"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component","name":"Infinite scroll in React with a real API example for web development","isPartOf":{"@id":"https:\/\/www.200oksolutions.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component#primaryimage"},"image":{"@id":"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component#primaryimage"},"thumbnailUrl":"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2025\/06\/How-to-Migrate-to-Cloud-Native-Architectures-Using-Microservices-1-2026-10-23T104417.512.png","datePublished":"2025-06-25T04:14:24+00:00","dateModified":"2026-10-23T05:22:58+00:00","description":"Learn infinite scroll in React three ways: React-infinite-scroll-component and TanStack Query. Code, comparison and SEO tips.","breadcrumb":{"@id":"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component#primaryimage","url":"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2025\/06\/How-to-Migrate-to-Cloud-Native-Architectures-Using-Microservices-1-2026-10-23T104417.512.png","contentUrl":"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2025\/06\/How-to-Migrate-to-Cloud-Native-Architectures-Using-Microservices-1-2026-10-23T104417.512.png","width":2240,"height":1260,"caption":"Infinite scroll in React with a real API example for web development | 200OK Solutions"},{"@type":"BreadcrumbList","@id":"https:\/\/www.200oksolutions.com\/blog\/infinite-scroll-react-using-react-infinite-scroll-component#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.200oksolutions.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Blog >React > Infinite Scroll in React with a Real API Example"}]},{"@type":"WebSite","@id":"https:\/\/www.200oksolutions.com\/blog\/#website","url":"https:\/\/www.200oksolutions.com\/blog\/","name":"Web Development, Software, and App Blog | 200OK Solutions","description":"","publisher":{"@id":"https:\/\/www.200oksolutions.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.200oksolutions.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.200oksolutions.com\/blog\/#organization","name":"200OK Solutions","url":"https:\/\/www.200oksolutions.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.200oksolutions.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2025\/09\/200ok_logo-CGzMrWDu.png","contentUrl":"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2025\/09\/200ok_logo-CGzMrWDu.png","width":500,"height":191,"caption":"200OK Solutions"},"image":{"@id":"https:\/\/www.200oksolutions.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.instagram.com\/200ok_solutions\/"]},{"@type":"Person","@id":"https:\/\/www.200oksolutions.com\/blog\/#\/schema\/person\/e07f6b8e3c9a90ce7b3b09427d26155e","name":"Piyush Solanki","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.200oksolutions.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2026\/05\/cropped-piyush-solanki-96x96.jpg","contentUrl":"https:\/\/www.200oksolutions.com\/blog\/wp-content\/uploads\/2026\/05\/cropped-piyush-solanki-96x96.jpg","caption":"Piyush Solanki"},"description":"Piyush is a seasoned PHP Tech Lead with 10+ years of experience architecting and delivering scalable web and mobile backend solutions for global brands and fast-growing SMEs. He specializes in PHP, MySQL, CodeIgniter, WordPress, and custom API development, helping businesses modernize legacy systems and launch secure, high-performance digital products. He collaborates closely with mobile teams building Android &amp; iOS apps , developing RESTful APIs, cloud integrations, and secure payment systems using platforms like Stripe, AWS S3, and OTP\/SMS gateways. His work extends across CMS customization, microservices-ready backend architectures, and smooth product deployments across Linux and cloud-based environments. Piyush also has a strong understanding of modern front-end technologies such as React and TypeScript, enabling him to contribute to full-stack development workflows and advanced admin panels. With a successful delivery track record in the UK market and experience building digital products for sectors like finance, hospitality, retail, consulting, and food services, Piyush is passionate about helping SMEs scale technology teams, improve operational efficiency, and accelerate innovation through backend excellence and digital tools.","url":"https:\/\/www.200oksolutions.com\/blog\/author\/piyush\/"}]}},"_links":{"self":[{"href":"https:\/\/www.200oksolutions.com\/blog\/wp-json\/wp\/v2\/posts\/2398","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.200oksolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.200oksolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.200oksolutions.com\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.200oksolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=2398"}],"version-history":[{"count":7,"href":"https:\/\/www.200oksolutions.com\/blog\/wp-json\/wp\/v2\/posts\/2398\/revisions"}],"predecessor-version":[{"id":5310,"href":"https:\/\/www.200oksolutions.com\/blog\/wp-json\/wp\/v2\/posts\/2398\/revisions\/5310"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.200oksolutions.com\/blog\/wp-json\/wp\/v2\/media\/5308"}],"wp:attachment":[{"href":"https:\/\/www.200oksolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=2398"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.200oksolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=2398"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.200oksolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=2398"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}