ReactList: Infinite Scroll Component
ReactList is a versatile React component designed for rendering large, scrollable lists efficiently. It leverages virtualization techniques to render only the visible items, significantly improving performance for long lists. Currently at version 0.8.18, it maintains broad compatibility with React versions from 0.14 through 19. While a 0.x.x version suggests a pre-1.0 stable release, its ongoing compatibility with modern React indicates active maintenance. Key differentiators include support for different item sizing strategies via its `type` prop (uniform, variable, simple), custom item and items renderers, and flexible control over the scroll parent, making it adaptable to various UI layouts and performance needs. It focuses on providing a performant scrolling experience without over-rendering DOM elements.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'name') at MyComponent.renderItem
cause The `length` prop for ReactList might be out of sync with the actual data array, or `renderItem` is called with an `index` for which no data exists.fixEnsure `this.state.accounts` is properly populated before rendering the list and that `length={this.state.accounts.length}` accurately reflects the current data count. Add a null/undefined check inside `renderItem` for defensive rendering. -
ReactList is not scrolling or items are not loading as expected.
cause The container element for ReactList is missing `overflow: auto` or `overflow: scroll` CSS properties, or the `scrollParentGetter` prop is misconfigured, preventing the list from detecting a scrollable parent.fixEnsure the direct parent of `<ReactList />` has a defined height and `overflow: auto` or `overflow: scroll` styles. If a custom scroll parent is used, verify the `scrollParentGetter` correctly returns the scrollable DOM element or `window`. -
Items in ReactList have incorrect heights/widths or overlap, especially when their sizes vary.
cause The `type` prop is set incorrectly (e.g., `'uniform'` for variable-sized items) or `itemSizeGetter` is not provided/incorrectly implemented for `type='variable'`.fixFor variable-sized items, set `type='variable'` and provide an `itemSizeGetter(index)` function that accurately returns the size of the item at that index. If exact sizes are unknown before rendering, consider `itemSizeEstimator`.
Warnings
- breaking ReactList uses a 0.x.x versioning scheme. This implies that breaking changes may occur in minor or even patch releases, so always review changelogs when upgrading.
- gotcha When using the `itemsRenderer` prop, it is critical to pass the `ref` prop (received as an argument to `itemsRenderer`) to the root DOM element or component that contains the rendered items. Failure to do so will prevent correct item sizing calculations and lead to rendering issues.
- gotcha The `itemSizeEstimator` and `itemSizeGetter` props are only utilized when the `type` prop is set to `'variable'`. Misconfiguring these (e.g., providing them with `type='uniform'`) will result in them being ignored and potentially incorrect list behavior.
- deprecated The `README` mentions installation via Bower (`bower install react-list`). Bower is a deprecated package manager and should not be used for new projects. NPM or Yarn are the standard.
Install
-
npm install react-list -
yarn add react-list -
pnpm add react-list
Imports
- ReactList
import { ReactList } from 'react-list'; const ReactList = require('react-list');import ReactList from 'react-list';
Quickstart
import React from 'react';
import ReactList from 'react-list';
// Mock data loading function
const loadAccounts = (callback) => {
setTimeout(() => {
const accounts = Array.from({ length: 1000 }, (_, i) => ({ id: i, name: `Account ${i + 1}` }));
callback(accounts);
}, 50);
};
class MyComponent extends React.Component {
state = {
accounts: []
};
componentDidMount() {
loadAccounts(this.handleAccounts);
}
handleAccounts = (accounts) => {
this.setState({ accounts });
};
renderItem = (index, key) => {
const account = this.state.accounts[index];
if (!account) return null; // Handle cases where data might be loading or out of sync
return <div key={key} style={{ padding: '10px', borderBottom: '1px solid #eee' }}>{account.name}</div>;
};
render() {
return (
<div>
<h1>Accounts</h1>
<div style={{ overflow: 'auto', maxHeight: 400, border: '1px solid #ccc' }}>
<ReactList
itemRenderer={this.renderItem}
length={this.state.accounts.length}
type='uniform'
threshold={200}
/>
</div>
<p>Showing {this.state.accounts.length} accounts.</p>
</div>
);
}
}
// Example of how to use it in a parent component (for demonstration)
// function App() {
// return <MyComponent />;
// }
// export default App;