react-infinite-scroll-component vs react-infinite-scroll-component
React 无限滚动组件库选型对比
react-infinite-scroll-componentreact-infinite-scroll-component
React 无限滚动组件库选型对比

react-infinite-scroll-component 是一个用于在 React 应用中实现无限滚动(Infinite Scroll)功能的轻量级组件库。它允许开发者在用户滚动到容器底部时自动加载更多内容,常用于长列表、消息流或分页数据的懒加载场景。该组件封装了滚动事件监听、加载状态管理以及占位符渲染等逻辑,简化了无限滚动的实现复杂度。

npm下载趋势
3 年
GitHub Stars 排名
统计详情
npm包名称
下载量
Stars
大小
Issues
发布时间
License
react-infinite-scroll-component898,9863,046169 kB1982 天前MIT
react-infinite-scroll-component898,9863,046169 kB1982 天前MIT

react-infinite-scroll-component 自我重复项分析:为何列表中出现两次相同包名?

在本次比较中,您提供的两个包名均为 react-infinite-scroll-component —— 这是同一个 npm 包被重复列出,并非两个不同的库。因此,不存在技术差异或选型问题。但我们仍可借此机会深入剖析该库的实际能力、适用边界和潜在陷阱,帮助专业开发者判断是否应在新项目中采用它。

📦 核心功能与使用方式

react-infinite-scroll-component 的核心是一个 React 组件,通过监听滚动事件,在用户接近容器底部时触发 next() 回调以加载更多数据。它内置了加载中提示(如 spinner)和“无更多数据”状态的 UI 管理。

import InfiniteScroll from 'react-infinite-scroll-component';

function MyList({ items, hasMore, loadMore }) {
  return (
    <div id="scrollableDiv" style={{ height: '400px', overflow: 'auto' }}>
      <InfiniteScroll
        dataLength={items.length}
        next={loadMore}
        hasMore={hasMore}
        loader={<h4>加载中...</h4>}
        scrollableTarget="scrollableDiv"
      >
        {items.map(item => <div key={item.id}>{item.name}</div>)}
      </InfiniteScroll>
    </div>
  );
}

关键属性说明:

  • dataLength:当前已加载的数据项数量,用于判断是否触发加载。
  • next:加载下一页数据的函数。
  • hasMore:布尔值,表示是否还有更多数据可加载。
  • loader:加载中的占位元素。
  • scrollableTarget:可选,指定滚动容器的 ID(默认监听 window 滚动)。

⚠️ 功能限制与工程考量

尽管该组件上手简单,但在真实项目中需警惕以下限制:

1. 仅支持垂直滚动

该库无法处理水平无限滚动场景。如果你的 UI 需要横向滑动加载(如图片轮播、时间轴),此库不适用。

2. 滚动容器依赖 DOM ID

通过 scrollableTarget 指定滚动容器时,必须传入字符串 ID。这在动态生成的组件或严格遵循 React ref 模式的现代代码中显得笨拙,且容易因 ID 冲突导致行为异常。

// 不推荐:硬编码 ID,难以复用
<div id="my-list-container">
  <InfiniteScroll scrollableTarget="my-list-container" ... />
</div>

相比之下,更现代的方案(如 react-intersection-observer + 自定义逻辑)可直接使用 React refs,避免全局 ID 依赖。

3. 缺乏性能优化机制

该组件未内置虚拟滚动(virtualization)支持。当列表项数量极大(如上千条)时,DOM 节点过多会导致内存占用高、滚动卡顿。此时应考虑 react-windowreact-virtual 等结合无限滚动的方案。

4. 错误处理与重试缺失

加载失败时,组件不会自动提供“重试”按钮或错误状态反馈。开发者需自行在外层管理加载状态和错误恢复逻辑,增加了业务复杂度。

// 需手动处理错误状态
const [error, setError] = useState(null);

const loadMore = async () => {
  try {
    await fetchData();
    setError(null);
  } catch (err) {
    setError(err);
  }
};

// 在 loader 中额外渲染错误提示
{error && <button onClick={loadMore}>重试</button>}

🔍 维护状态与替代方案建议

截至最新验证,react-infinite-scroll-component 在 npm 和 GitHub 上未被官方标记为废弃(deprecated),但其最近一次显著更新已较为久远,且 issue 区存在若干未解决的兼容性问题(如与 Strict Mode 冲突)。对于新项目,建议评估以下替代路径:

  • 轻量级自定义实现:使用 IntersectionObserver API 监听底部哨兵元素,代码量少且完全可控。
function useInfiniteScroll(callback) {
  const sentinelRef = useRef();

  useEffect(() => {
    const observer = new IntersectionObserver(entries => {
      if (entries[0].isIntersecting) callback();
    });
    if (sentinelRef.current) observer.observe(sentinelRef.current);
    return () => observer.disconnect();
  }, [callback]);

  return sentinelRef;
}

// 使用
const sentinelRef = useInfiniteScroll(loadMore);
return (
  <>
    {items.map(item => <div key={item.id}>{item.name}</div>)}
    <div ref={sentinelRef} />
  </>
);
  • 功能更全面的库:如 react-waypoint(通用滚动触发点)或结合 react-query 的分页 hooks,可获得更好的状态管理和缓存能力。

✅ 何时仍可使用 react-infinite-scroll-component?

  • 项目为中小型应用,列表数据量有限(< 200 项)。
  • 无需水平滚动、虚拟化或复杂错误恢复。
  • 团队追求快速交付,不愿引入额外逻辑。

📌 总结

虽然 react-infinite-scroll-component 提供了简洁的 API,但其设计较为陈旧,缺乏现代 React 应用所需的灵活性和健壮性。在新项目中,除非需求极其简单,否则建议优先考虑基于 IntersectionObserver 的自定义方案或更活跃维护的替代库。对于已有项目中正在使用的实例,若运行稳定,可继续维护,但应避免在新模块中扩展其使用范围。

如何选择: react-infinite-scroll-component vs react-infinite-scroll-component
  • react-infinite-scroll-component:

    由于所列两个包名完全相同,实际指向同一个 npm 包 react-infinite-scroll-component,因此不存在选型差异。若项目需要简单、开箱即用的无限滚动功能,且数据源为垂直方向的线性列表,可直接使用此包。但需注意其不支持水平滚动、自定义滚动容器(仅限 window 或指定 DOM 容器)等高级场景,且长期未有重大更新,建议评估是否满足当前项目需求。

  • react-infinite-scroll-component:

    由于所列两个包名完全相同,实际指向同一个 npm 包 react-infinite-scroll-component,因此不存在选型差异。若项目需要简单、开箱即用的无限滚动功能,且数据源为垂直方向的线性列表,可直接使用此包。但需注意其不支持水平滚动、自定义滚动容器(仅限 window 或指定 DOM 容器)等高级场景,且长期未有重大更新,建议评估是否满足当前项目需求。

react-infinite-scroll-component的README

react-infinite-scroll-component npm npm

All Contributors

A component to make all your infinite scrolling woes go away with just 4.15 kB! Pull Down to Refresh feature added. An infinite-scroll that actually works and super-simple to integrate!

Install

  npm install --save react-infinite-scroll-component

  or

  yarn add react-infinite-scroll-component

  // in code ES6
  import InfiniteScroll from 'react-infinite-scroll-component';
  // or commonjs
  var InfiniteScroll = require('react-infinite-scroll-component');

Using

<InfiniteScroll
  dataLength={items.length} //This is important field to render the next data
  next={fetchData}
  hasMore={true}
  loader={<h4>Loading...</h4>}
  endMessage={
    <p style={{ textAlign: 'center' }}>
      <b>Yay! You have seen it all</b>
    </p>
  }
  // below props only if you need pull down functionality
  refreshFunction={this.refresh}
  pullDownToRefresh
  pullDownToRefreshThreshold={50}
  pullDownToRefreshContent={
    <h3 style={{ textAlign: 'center' }}>&#8595; Pull down to refresh</h3>
  }
  releaseToRefreshContent={
    <h3 style={{ textAlign: 'center' }}>&#8593; Release to refresh</h3>
  }
>
  {items}
</InfiniteScroll>

Using scroll on top

<div
  id="scrollableDiv"
  style={{
    height: 300,
    overflow: 'auto',
    display: 'flex',
    flexDirection: 'column-reverse',
  }}
>
  {/*Put the scroll bar always on the bottom*/}
  <InfiniteScroll
    dataLength={this.state.items.length}
    next={this.fetchMoreData}
    style={{ display: 'flex', flexDirection: 'column-reverse' }} //To put endMessage and loader to the top.
    inverse={true} //
    hasMore={true}
    loader={<h4>Loading...</h4>}
    scrollableTarget="scrollableDiv"
  >
    {this.state.items.map((_, index) => (
      <div style={style} key={index}>
        div - #{index}
      </div>
    ))}
  </InfiniteScroll>
</div>

The InfiniteScroll component can be used in three ways.

  • Specify a value for the height prop if you want your scrollable content to have a specific height, providing scrollbars for scrolling your content and fetching more data.
  • If your scrollable content is being rendered within a parent element that is already providing overflow scrollbars, you can set the scrollableTarget prop to reference the DOM element and use it's scrollbars for fetching more data.
  • Without setting either the height or scrollableTarget props, the scroll will happen at document.body like Facebook's timeline scroll.

docs version wise

3.0.2

live examples

  • infinite scroll (never ending) example using react (body/window scroll)
    • Edit yk7637p62z
  • infinte scroll till 500 elements (body/window scroll)
    • Edit 439v8rmqm0
  • infinite scroll in an element (div of height 400px)
    • Edit w3w89k7x8
  • infinite scroll with scrollableTarget (a parent element which is scrollable)
    • Edit r7rp40n0zm

props

nametypedescription
nextfunctiona function which must be called after reaching the bottom. It must trigger some sort of action which fetches the next data. The data is passed as children to the InfiniteScroll component and the data should contain previous items too. e.g. Initial data = [1, 2, 3] and then next load of data should be [1, 2, 3, 4, 5, 6].
hasMorebooleanit tells the InfiniteScroll component on whether to call next function on reaching the bottom and shows an endMessage to the user
childrennode (list)the data items which you need to scroll.
dataLengthnumberset the length of the data.This will unlock the subsequent calls to next.
loadernodeyou can send a loader component to show while the component waits for the next load of data. e.g. <h3>Loading...</h3> or any fancy loader element
scrollThresholdnumber | stringA threshold value defining when InfiniteScroll will call next. Default value is 0.8. It means the next will be called when user comes below 80% of the total height. If you pass threshold in pixels (scrollThreshold="200px"), next will be called once you scroll at least (100% - scrollThreshold) pixels down.
onScrollfunctiona function that will listen to the scroll event on the scrolling container. Note that the scroll event is throttled, so you may not receive as many events as you would expect.
endMessagenodethis message is shown to the user when he has seen all the records which means he's at the bottom and hasMore is false
classNamestringadd any custom class you want
styleobjectany style which you want to override
heightnumberoptional, give only if you want to have a fixed height scrolling content
scrollableTargetnode or stringoptional, reference to a (parent) DOM element that is already providing overflow scrollbars to the InfiniteScroll component. You should provide the id of the DOM node preferably.
hasChildrenboolchildren is by default assumed to be of type array and it's length is used to determine if loader needs to be shown or not, if your children is not an array, specify this prop to tell if your items are 0 or more.
pullDownToRefreshboolto enable Pull Down to Refresh feature
pullDownToRefreshContentnodeany JSX that you want to show the user, default={<h3>Pull down to refresh</h3>}
releaseToRefreshContentnodeany JSX that you want to show the user, default={<h3>Release to refresh</h3>}
pullDownToRefreshThresholdnumberminimum distance the user needs to pull down to trigger the refresh, default=100px , a lower value may be needed to trigger the refresh depending your users browser.
refreshFunctionfunctionthis function will be called, it should return the fresh data that you want to show the user
initialScrollYnumberset a scroll y position for the component to render with.
inverseboolset infinite scroll on top

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Ankeet Maini

💬 📖 💻 👀 🚧

Darsh Shah

🚇

This project follows the all-contributors specification. Contributions of any kind are welcome!

LICENSE

MIT

react-infinite-scroll-component的README

react-infinite-scroll-component npm npm

All Contributors

A component to make all your infinite scrolling woes go away with just 4.15 kB! Pull Down to Refresh feature added. An infinite-scroll that actually works and super-simple to integrate!

Install

  npm install --save react-infinite-scroll-component

  or

  yarn add react-infinite-scroll-component

  // in code ES6
  import InfiniteScroll from 'react-infinite-scroll-component';
  // or commonjs
  var InfiniteScroll = require('react-infinite-scroll-component');

Using

<InfiniteScroll
  dataLength={items.length} //This is important field to render the next data
  next={fetchData}
  hasMore={true}
  loader={<h4>Loading...</h4>}
  endMessage={
    <p style={{ textAlign: 'center' }}>
      <b>Yay! You have seen it all</b>
    </p>
  }
  // below props only if you need pull down functionality
  refreshFunction={this.refresh}
  pullDownToRefresh
  pullDownToRefreshThreshold={50}
  pullDownToRefreshContent={
    <h3 style={{ textAlign: 'center' }}>&#8595; Pull down to refresh</h3>
  }
  releaseToRefreshContent={
    <h3 style={{ textAlign: 'center' }}>&#8593; Release to refresh</h3>
  }
>
  {items}
</InfiniteScroll>

Using scroll on top

<div
  id="scrollableDiv"
  style={{
    height: 300,
    overflow: 'auto',
    display: 'flex',
    flexDirection: 'column-reverse',
  }}
>
  {/*Put the scroll bar always on the bottom*/}
  <InfiniteScroll
    dataLength={this.state.items.length}
    next={this.fetchMoreData}
    style={{ display: 'flex', flexDirection: 'column-reverse' }} //To put endMessage and loader to the top.
    inverse={true} //
    hasMore={true}
    loader={<h4>Loading...</h4>}
    scrollableTarget="scrollableDiv"
  >
    {this.state.items.map((_, index) => (
      <div style={style} key={index}>
        div - #{index}
      </div>
    ))}
  </InfiniteScroll>
</div>

The InfiniteScroll component can be used in three ways.

  • Specify a value for the height prop if you want your scrollable content to have a specific height, providing scrollbars for scrolling your content and fetching more data.
  • If your scrollable content is being rendered within a parent element that is already providing overflow scrollbars, you can set the scrollableTarget prop to reference the DOM element and use it's scrollbars for fetching more data.
  • Without setting either the height or scrollableTarget props, the scroll will happen at document.body like Facebook's timeline scroll.

docs version wise

3.0.2

live examples

  • infinite scroll (never ending) example using react (body/window scroll)
    • Edit yk7637p62z
  • infinte scroll till 500 elements (body/window scroll)
    • Edit 439v8rmqm0
  • infinite scroll in an element (div of height 400px)
    • Edit w3w89k7x8
  • infinite scroll with scrollableTarget (a parent element which is scrollable)
    • Edit r7rp40n0zm

props

nametypedescription
nextfunctiona function which must be called after reaching the bottom. It must trigger some sort of action which fetches the next data. The data is passed as children to the InfiniteScroll component and the data should contain previous items too. e.g. Initial data = [1, 2, 3] and then next load of data should be [1, 2, 3, 4, 5, 6].
hasMorebooleanit tells the InfiniteScroll component on whether to call next function on reaching the bottom and shows an endMessage to the user
childrennode (list)the data items which you need to scroll.
dataLengthnumberset the length of the data.This will unlock the subsequent calls to next.
loadernodeyou can send a loader component to show while the component waits for the next load of data. e.g. <h3>Loading...</h3> or any fancy loader element
scrollThresholdnumber | stringA threshold value defining when InfiniteScroll will call next. Default value is 0.8. It means the next will be called when user comes below 80% of the total height. If you pass threshold in pixels (scrollThreshold="200px"), next will be called once you scroll at least (100% - scrollThreshold) pixels down.
onScrollfunctiona function that will listen to the scroll event on the scrolling container. Note that the scroll event is throttled, so you may not receive as many events as you would expect.
endMessagenodethis message is shown to the user when he has seen all the records which means he's at the bottom and hasMore is false
classNamestringadd any custom class you want
styleobjectany style which you want to override
heightnumberoptional, give only if you want to have a fixed height scrolling content
scrollableTargetnode or stringoptional, reference to a (parent) DOM element that is already providing overflow scrollbars to the InfiniteScroll component. You should provide the id of the DOM node preferably.
hasChildrenboolchildren is by default assumed to be of type array and it's length is used to determine if loader needs to be shown or not, if your children is not an array, specify this prop to tell if your items are 0 or more.
pullDownToRefreshboolto enable Pull Down to Refresh feature
pullDownToRefreshContentnodeany JSX that you want to show the user, default={<h3>Pull down to refresh</h3>}
releaseToRefreshContentnodeany JSX that you want to show the user, default={<h3>Release to refresh</h3>}
pullDownToRefreshThresholdnumberminimum distance the user needs to pull down to trigger the refresh, default=100px , a lower value may be needed to trigger the refresh depending your users browser.
refreshFunctionfunctionthis function will be called, it should return the fresh data that you want to show the user
initialScrollYnumberset a scroll y position for the component to render with.
inverseboolset infinite scroll on top

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Ankeet Maini

💬 📖 💻 👀 🚧

Darsh Shah

🚇

This project follows the all-contributors specification. Contributions of any kind are welcome!

LICENSE

MIT