Skip to content

thermarthae/react-smartlist

Repository files navigation

@thermarthae/react-smartlist

Version Badge GZipped size License Downloads

React helper component that uses window scrolling to render only currently visible list elements.

Uses React's internal scheduler to prevent redundant rerenders and prioritize most recent scroll events.

Installation

Install using Yarn:

yarn add @thermarthae/react-smartlist

or NPM:

npm install @thermarthae/react-smartlist --save

Example

Interactive Typescript example:

Edit @thermarthae/react-smartlist example

Basic example:

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import VirtualList from '@thermarthae/react-smartlist';

const ListItem = React.memo(({
  rootElProps,
  innerRef,
  data,
}) => (
  <div
    {...rootElProps}
    ref={innerRef}
    style={{
      ...rootElProps.style,
      height: data.height,
      backgroundColor: `hsl(${Math.round(Math.random() * 360)}deg 50% 50%)`
    }}
  >
    ListItem {data.id}
  </div>
));

const getItemKey = (item) => item.id;

const App = () => {
  const data = [...Array(1000)].map((_v, index) => ({
    id: index,
    height: (index % 10 === 0) ? 100 : 50,
  }))

  return (
    <div>
      {/* Place for header, title, whatever... */}
      <VirtualList
        items={data}
        itemKey={getItemKey}
        overscanPadding={100}
        estimatedItemHeight={50}
        component={ListItem}
      />
    </div>
  );
};

const rootElement = document.getElementById('root');
ReactDOM.render(<App />, rootElement);

Props

Name Description
component Your component that is used to render a single list item.
items An array of actual data mapped to all children.
estimatedItemHeight The estimated height of a single rendered item.

In a best-case scenario, the same as actual item height.

Every item has its dimensions that are being used to calculate the height of a whole list. Thanks to that, the browser can allocate necessary space and display the scrollbars. It creates an illusion that all elements are present and visible at the same time.

But how can we know the dimensions of an actual item before the initial render? Well, we don't. That's where estimatedItemHeight kicks in. We use a placeholder to compute all necessary values, then when the actual items are rendered, we measure them and repeats all calculations.
itemKey A factory function that returns (extracts) an ID from the item.

Every item in the list must be identified by its unique ID.

Remember that this function will be called many times, so any fancy function may negatively affect your rendering performance.
overscanPadding This value increases the overall viewport area. Defines how many pixels beyond the horizon should be overscaned.

In other words, this is a value that allows you to render more elements than can be actually seen on the screen.
className Custom CSS classname attached to a VirtualList root element.
sharedProps Props passed to every rendered item.
initState An advanced prop that can be used to overwrite the initial VirtualList state. Proceed with caution.
disableMeasurment Disables the item measurements and sets estimatedItemHeight as an actual element height.

Useful when your list consists of items with equal heights.
onScroll Function invoked at the scroll event.

Keep this function as performant as possible.

License

This project is MIT licensed.