Hooks for virtualizing scrollable elements in React
Enjoy this library? Try them all! React Table, React Query, React Form, React Charts
- Row, Column, and Grid virtualization
 - One single headless hook
 - Fixed, variable and dynamic measurement modes
 - Imperative scrollTo control for offset, indices and alignment
 - Custom scrolling function support (eg. smooth scroll)
 - 
 
- Fixed Rows/Cols/Grid- CodeSandbox - Source
 - Variable Rows/Cols/Grid- CodeSandbox - Source
 - Dynamic Rows/Cols/Grid- CodeSandbox - Source
 - Smooth Scrolling - CodeSandbox - Source
 - Infinite Scrolling - CodeSandbox - Source
 
This library is being built and maintained by me, @tannerlinsley and I am always in need of more support to keep projects like this afloat. If you would like to get premium support, add your logo or name on this README, or simply just contribute to my open source Sponsorship goal, visit my Github Sponsors page!
| Get Your Logo Here! | 
| Get Your Logo Here! | 
        
           
        
       | 
    
| Get Your Logo Here! | 
| Get Your Name Here! | 
| Get Your Name Here! | 
$ npm i --save react-virtual
# or
$ yarn add react-virtualReact Virtual's most distinguishing feature is that it's just one single custom hook instead of a set of components. In more trendy terms, this means that it is "headless", allowing you to control 100% all of the markup and styles, exactly how you want.
React Virtual supplies you with primitive utilities that allow you to build any range of virtualized experiences. One testament to this is that you can combine 2 instances of useVirtual onto the same markup to achieve a virtualized grid, where with other utilites, you would need to use a dedicated Grid-like component.
This is just a quick sample of what it looks like to use React Virtual. Please refer to the examples for more usage patterns.
function RowVirtualizerFixed() {
  const parentRef = React.useRef()
  const rowVirtualizer = useVirtual({
    size: 10000,
    parentRef,
    estimateSize: React.useCallback(() => 35, []),
  })
  return (
    <>
      <div
        ref={parentRef}
        className="List"
        style={{
          height: `150px`,
          width: `300px`,
          overflow: 'auto',
        }}
      >
        <div
          className="ListInner"
          style={{
            height: `${rowVirtualizer.totalSize}px`,
            width: '100%',
            position: 'relative',
          }}
        >
          {rowVirtualizer.virtualItems.map(virtualRow => (
            <div
              key={virtualRow.index}
              className={virtualRow.index % 2 ? 'ListItemOdd' : 'ListItemEven'}
              style={{
                position: 'absolute',
                top: 0,
                left: 0,
                width: '100%',
                height: `${virtualRow.size}px`,
                transform: `translateY(${virtualRow.start}px)`,
              }}
            >
              Row {virtualRow.index}
            </div>
          ))}
        </div>
      </div>
    </>
  )
}const {
  virtualItems: [
    { index, start, size, end, measureRef },
    /* ... */
  ],
  totalSize,
  scrollToIndex,
  scrollToOffset,
} = useVirtual({
  size,
  parentRef,
  estimateSize,
  overscan,
  horizontal,
  scrollToFn,
})size: Integer- Required
 - The size of the virtualizer
 
parentRef: React.useRef(DOMElement)- Required
 - The parent element whose inner-content is scrollable
 
estimateSize: Function(index) => Integer- Required
 - Must be memoized using 
React.useCallback() - This function receives the index of each item and should return either:
- A fixed size
 - A variable size per-item
 - A best-guess size (when using dynamic measurement rendering)
 
 - When this function's memoization changes, the entire list is recalculated
 
overscan: Integer- Defaults to 
1 - The amount of items to load both behind and ahead of the current window range
 
- Defaults to 
 horizontal: Boolean- Defaults to 
false - When 
true, this virtualizer will usewidthandscrollLeftinstead ofheightandscrollTopto determine size and offset of virtualized items. 
- Defaults to 
 scrollToFn: Function(offset, defaultScrollToFn) => void 0- Optional
 - This function, if passed, is responsible for implementing the scrollTo log for the parentRef which is used when methods like 
scrolllToOffsetandscrollToIndexare called. - Eg. You can use this function implement smooth scrolling by using the supplied offset and the 
defaultScrollToFnas seen in the sandbox's Smooth Scroll example. 
paddingStart: Integer- Defaults to 
0 - The amount of padding in pixels to add to the start of the virtual list
 
- Defaults to 
 paddingEnd: Integer- Defaults to 
0 - The amount of padding in pixels to add to the end of the virtual list
 
- Defaults to 
 
virtualItems: Array<item>item: Objectindex: Integer- The index of the item
 
start: Integer- The starting measurement of the item
 - Most commonly used for positioning elements
 
size: Integer- The static/variable or, if dynamically rendered, the measured size of the item
 
end: Integer- The ending measurement of the item
 
measureRef: React.useRef | Function(el: DOMElement) => void 0- The ref/function to place on the rendered element to enable dynamic measurement rendering
 
totalSize: Integer- The total size of the entire virtualizer
 - When using dynamic measurement refs, this number may change as items are measured after they are rendered.
 
scrollToIndex: Function(index: Integer, { align: String }) => void 0- Call this function to scroll the top/left of the parentRef element to the start of the item located at the passed index.
 align: 'start' | 'center' | 'end' | 'auto'- Defaults to 
auto startplaces the item at the top/left of the visible scroll areacenterplaces the item in the center of the visible scroll areaendplaces the item at the bottom/right of the visible scroll areaautobrings the item into the visible scroll area either at the start or end, depending on which is closer. If the item is already in view, it is placed at thetop/leftof the visible scroll area.
- Defaults to 
 
scrollToOffset: Function(offsetInPixels: Integer, { align: String }) => void 0- Call this function to scroll the top/left of the parentRef element to the passed pixel offset.
 align: 'start' | 'center' | 'end' | 'auto'- Defaults to 
start startplaces the offset at the top/left of the visible scroll areacenterplaces the offset in the center of the visible scroll areaendplaces the offset at the bottom/right of the visible scroll areaautobrings the offset into the visible scroll area either at the start or end, depending on which is closer. If the offset is already in view, it is placed at thetop/leftof the visible scroll area.
- Defaults to 
 
Thanks goes to these wonderful people (emoji key):
Tanner Linsley 💻 🤔 💡 🚧 👀  | 
  
This project follows the all-contributors specification. Contributions of any kind welcome!





        

