{"id":11725,"library":"react-infinite-scroll-component","title":"React Infinite Scroll Component","description":"`react-infinite-scroll-component` is a lightweight (4.15 kB) and efficient React component designed to implement infinite scrolling experiences in web applications. The current stable version is v7.1.0, with an active development cadence indicated by recent major and minor releases. A key differentiator is its transition to an `IntersectionObserver`-based triggering mechanism in v7.1.0, which enhances performance by running off the main thread and eliminating the need for scroll event throttling, leading to zero runtime dependencies. It supports conventional bottom-to-top scrolling, inverse scrolling (top-to-bottom), and a \"pull down to refresh\" feature. The component can operate on the document body, within a fixed-height container, or target a specific scrollable DOM element via its ID or a direct `HTMLElement` reference, offering flexibility in integration scenarios. It also requires React 17+ and Node.js 18.18.0+ for development.","status":"active","version":"7.1.0","language":"javascript","source_language":"en","source_url":"https://github.com/ankeetmaini/react-infinite-scroll-component","tags":["javascript","react","infinite-scroll","infinite","scroll","component","react-component","typescript"],"install":[{"cmd":"npm install react-infinite-scroll-component","lang":"bash","label":"npm"},{"cmd":"yarn add react-infinite-scroll-component","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-infinite-scroll-component","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency for React components.","package":"react","optional":false},{"reason":"Peer dependency for rendering React components.","package":"react-dom","optional":false}],"imports":[{"note":"The `InfiniteScroll` component is a default export for ESM/TypeScript environments.","wrong":"import { InfiniteScroll } from 'react-infinite-scroll-component';","symbol":"InfiniteScroll","correct":"import InfiniteScroll from 'react-infinite-scroll-component';"},{"note":"For CommonJS environments, `InfiniteScroll` is also a default export.","wrong":"const { InfiniteScroll } = require('react-infinite-scroll-component');","symbol":"InfiniteScroll","correct":"const InfiniteScroll = require('react-infinite-scroll-component');"},{"note":"TypeScript users can import type definitions using `import type` for clarity and better tree-shaking.","wrong":"import { InfiniteScrollProps } from 'react-infinite-scroll-component';","symbol":"InfiniteScrollProps","correct":"import type { InfiniteScrollProps } from 'react-infinite-scroll-component';"}],"quickstart":{"code":"import React, { useState } from 'react';\nimport InfiniteScroll from 'react-infinite-scroll-component';\n\ninterface Item {\n  id: number;\n  content: string;\n}\n\nconst style = {\n  padding: 15,\n  borderBottom: '1px solid #eee',\n  minHeight: 50,\n};\n\nconst App: React.FC = () => {\n  const [items, setItems] = useState<Item[]>(\n    Array.from({ length: 20 }, (_, i) => ({ id: i, content: `Initial Item #${i}` }))\n  );\n  const [hasMore, setHasMore] = useState(true);\n\n  const fetchMoreData = () => {\n    if (items.length >= 100) {\n      setHasMore(false);\n      return;\n    }\n    // Simulate an API call\n    setTimeout(() => {\n      setItems((prevItems) => [\n        ...prevItems,\n        ...Array.from({ length: 20 }, (_, i) => ({\n          id: prevItems.length + i,\n          content: `Fetched Item #${prevItems.length + i}`,\n        })),\n      ]);\n    }, 1500);\n  };\n\n  const refreshData = () => {\n    // Simulate re-fetching initial data for pull-to-refresh\n    return new Promise<void>((resolve) => {\n      setTimeout(() => {\n        setItems(Array.from({ length: 20 }, (_, i) => ({ id: i, content: `Refreshed Item #${i}` })));\n        setHasMore(true);\n        resolve();\n      }, 1000);\n    });\n  };\n\n  return (\n    <div>\n      <h1 style={{ textAlign: 'center' }}>Infinite Scroll Demo</h1>\n      <div\n        id=\"scrollableDiv\"\n        style={{\n          height: 400,\n          overflow: 'auto',\n          margin: '20px auto',\n          border: '1px solid #ccc',\n          width: '80%',\n        }}\n      >\n        <InfiniteScroll\n          dataLength={items.length}\n          next={fetchMoreData}\n          hasMore={hasMore}\n          loader={<h4>Loading...</h4>}\n          endMessage={\n            <p style={{ textAlign: 'center', padding: '10px' }}>\n              <b>Yay! You have seen it all</b>\n            </p>\n          }\n          refreshFunction={refreshData}\n          pullDownToRefresh\n          pullDownToRefreshThreshold={50}\n          pullDownToRefreshContent={\n            <h3 style={{ textAlign: 'center', margin: 0, padding: '10px' }}>&#8595; Pull down to refresh</h3>\n          }\n          releaseToRefreshContent={\n            <h3 style={{ textAlign: 'center', margin: 0, padding: '10px' }}>&#8593; Release to refresh</h3>\n          }\n          scrollableTarget=\"scrollableDiv\"\n        >\n          {items.map((item) => (\n            <div key={item.id} style={style}>\n              {item.content}\n            </div>\n          ))}\n        </InfiniteScroll>\n      </div>\n    </div>\n  );\n};\n\nexport default App;","lang":"typescript","description":"Demonstrates a basic infinite scroll setup with data loading, a loading indicator, an end message, and optional pull-down-to-refresh functionality within a defined scrollable container."},"warnings":[{"fix":"Upgrade your React and ReactDOM peer dependencies to version 17.0.0 or higher. Ensure your build configuration supports the new JSX transform.","message":"Version 7.0.0 introduced a breaking change requiring React 17.0.0 or newer. It also leverages the new JSX transform, meaning 'import React' boilerplate is no longer needed.","severity":"breaking","affected_versions":">=7.0.0"},{"fix":"Ensure your Node.js environment is version 18.18.0 or newer.","message":"Version 7.0.0 raised the minimum Node.js requirement to 18.18.0.","severity":"breaking","affected_versions":">=7.0.0"},{"fix":"Review any custom logic that interacted with scroll event throttling or relied on the `throttle-debounce` library. Adjust `onScroll` handlers if they expect throttled events, as they will now receive all events.","message":"Starting with v7.1.0, the core scroll-triggering mechanism changed from a throttled scroll event listener to an `IntersectionObserver`. This improves performance by running off the main thread and removed `throttle-debounce` as a dependency. The `onScroll` callback now receives *every* scroll event without internal throttling, which might alter behavior for code relying on the previously throttled events.","severity":"breaking","affected_versions":">=7.1.0"},{"fix":"You can now pass a `useRef` value or a direct DOM element to `scrollableTarget`, e.g., `scrollableTarget={myRef.current}` instead of just `scrollableTarget=\"myDivId\"`.","message":"The `scrollableTarget` prop now accepts a direct `HTMLElement` reference in addition to a string ID. While an improvement, developers should be aware of this expanded type signature for consistency.","severity":"gotcha","affected_versions":">=7.1.0"},{"fix":"Upgrade to `react-infinite-scroll-component@^7.0.1` or newer. If you were using `--legacy-peer-deps` or `--force` as a workaround, you can now remove these flags.","message":"Prior to v7.0.1, installing the package with React 18 or 19 could lead to peer dependency resolution errors (`ERESOLVE`) due to strict peer dependency declarations.","severity":"gotcha","affected_versions":"<7.0.1"},{"fix":"Always ensure `dataLength` accurately reflects the `length` of your `items` array or similar data source that holds your currently rendered content.","message":"The `dataLength` prop is crucial for correct functionality. It must represent the current total number of items rendered in the scrollable list. If it's not updated correctly as new items are loaded, the `next` function may not be triggered.","severity":"gotcha","affected_versions":">=5.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Upgrade `react-infinite-scroll-component` to version `^7.0.1` or newer. For example: `npm install react-infinite-scroll-component@latest`.","cause":"Attempting to install `react-infinite-scroll-component` versions older than 7.0.1 with React 18 or 19 due to strict peer dependency requirements.","error":"npm ERR! ERESOLVE unable to resolve dependency tree"},{"fix":"For `react-infinite-scroll-component@>=7.0.0`, ensure React is version 17+ and your build tool is configured for the new JSX transform (which removes the need for `import React`). If you are below v7, upgrade React and this package.","cause":"This error occurs in React 17+ projects that still include `import React from 'react';` at the top of JSX files, or when using `react-infinite-scroll-component@<7.0.0` with React 17+ configured for the new JSX transform without explicit `import React`.","error":"ReferenceError: React is not defined"},{"fix":"Verify that `dataLength` correctly reflects the current number of items, `hasMore` is `true` when more data is expected, and `scrollableTarget` (if used) correctly points to the scrollable container. Ensure your `next` function actually updates the state that `dataLength` depends on.","cause":"This usually indicates an issue with `dataLength` not being updated, `hasMore` being `false`, or incorrect `scrollableTarget` configuration (especially with `IntersectionObserver` in v7.1.0+).","error":"The 'next' prop function is not being called, or is called unexpectedly."}],"ecosystem":"npm"}