bestyled/flatlist
A performant, infinite, virtualized list for React. See react-virtualized
, react-window
and react-tiny-virtual-list
for prior art; this package is designed to
- Be extremely fast, with fine grained use of React Hooks (16.8+) instead of the less granular PureComponent used by existing solutions
- Delegate absolution positioning to the browser with use of FlexBox layout (removes need for
top
/size
styles on every element, as we simply observe what the browser does and then size the outer container accordingly) - Assumes variable size vertical items by default, with auto-resizing whenever the layout changes; if you want a FixedSizeList or Grid you may want to stick with
react-window
- Avoid dependencies on CellMeasurer and other techniques to pre-determine height of every item and instead build right in using a very simple react hook for ResizeObserver (polyfilled using react-resize-observer)
- Support scrolling to Index without calculating the size of all intermediate entries, particularly useful for Scroll-To-End based conversational user interfaces
- Removes advanced APIs like sticky index and sticks to the absolute minimum required to run a variable dynamic list
Unlike just about all other implemetations of virtualized lists for React, no old-school React Components inside, with just one code file for the Functional Component and one file for the Size and Position state manager.
Example Usage
import React from 'react'
import { render } from 'react-dom'
import { FlatList } from '@bestyled/contrib-flatlist'
import { AutoSizer } from '@bestyled/contrib-common'
// kick off the smoothscroll polyfill (for Safari, etc.)
import smoothscroll from 'smoothscroll-polyfill'
smoothscroll.polyfill()
const listItems = items.map((item, index) => (
<React.Fragment key={index}>
<RowHeader date={item.header} />
<RowCard item={item} />
</React.Fragment>
))
const renderRow = ({ index }) => {
return listItems[index]
}
render(
<AutoSizer flex={1} my={3}>
{({ height }) => (
<List
estimatedItemSize={100}
height={height}
itemCount={listItems.length}
scrollToIndex={listItems.length - 1}
scrollToAlignment="end"
renderItem={renderRow}
/>
)}
</AutoSizer>
)
Prop Types
Property | Type | Required? | Description |
---|---|---|---|
height | Number | String* | ✓ | Height of List. This property will determine the number of rendered items. |
itemCount | Number | ✓ | The number of items you want to render |
renderItem | Function | ✓ | Responsible for rendering an item given it's index: ({index: number}): React.PropTypes.node . The returned element must handle the given item key; any styling is up to you. |
scrollToIndex | Number | Item index to scroll to (by forcefully scrolling if necessary) x | |
scrollToAlignment | String | Used in combination with scrollToIndex , this prop controls the alignment of the scrolled to item. One of: 'start' , 'center' , 'end' or 'auto' . Use 'start' to always align items to the top of the container and 'end' to align them bottom. Use 'center ' to align them in the middle of the container. 'auto' scrolls the least amount possible to ensure that the specified scrollToIndex item is fully visible. |
|
stickyIndices | Number[] | An array of indexes (eg. [0, 10, 25, 30] ) to make certain items in the list sticky (position: sticky ) |
|
overscanCount | Number | Number of extra buffer items to render above/below the visible items. Tweaking this can help reduce scroll flickering on certain browsers/devices. | |
estimatedItemSize | Number | Used to estimate the total size of the list before all of its items have actually been measured. The estimated total height is progressively adjusted as items are rendered. | |
onScroll | Function | Callback invoked whenever the scroll offset changes within the inner scrollable region. It has the following signature: (scrollTop: number, event: React.UIEvent<HTMLDivElement>) . |
Dependencies
Three standalone React Hooks are used from @bestyled/contrib-common
. These could easily be incorporated yourself to eliminate this dependency. One of these has an additional depdency on ResizeObserver
polyfill
- useResizeObserver - simple wrapper around ResizeObserver to be notified whenever an element size has been changed
- useForceUpdate - convenience method to force a state change
- useInstanceRef - convenience method to lazy initialize an instance reference
Peer dependency on smoothscroll-polyfill
and react
License
Apache 2.0