Skip to content

oskarhane/react-virtual

 
 

Repository files navigation

React Virtual Header

Hooks for virtualizing scrollable elements in React

#TanStack semantic-release Join the discussion on Github

Enjoy this library? Try them all! React Table, React Virtual, React Form, React Charts

Quick Features

  • Row, Column, and Grid virtualization
  • One single headless hook
  • Fixed, variable and dynamic measurement modes

Examples

  • Sandbox - CodeSandbox - Source
    • Shows examples of Row, Column, and Grid layouts
    • Shows examples of fixed, variable, and dynamic sizing

Sponsors

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!

Become a Sponsor!
Become a Sponsor!
Become a Sponsor!
Become a Sponsor!
Become a Supporter!
Become a Fan!

Documentation

Installation

$ npm i --save react-virtual
# or
$ yarn add react-virtual

React Virtual uses Scarf to collect anonymized installation analytics. These analytics help support the maintainers of this library. However, if you'd like to opt out, you can do so by setting scarfSettings.enabled = false in your project's package.json. Alternatively, you can set the environment variable SCARF_ANALYTICS=false before you install.

Sample

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.items.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>
    </>
  )
}

API

useVirtual

const {
  items: [
    { index, start, size, end, measureRef },
    /* ... */
  ],
  totalSize,
} = useVirtual({
  size,
  parentRef,
  estimateSize,
  overscan,
  horiztonal,
})

Options

  • 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 recieves 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
    • The amount of items to load both behind and ahead of the current window range
    • Defaults to 1
  • horizontal: Boolean
    • When true, this virtualizer will use width and scrollLeft instead of height and scrollTop to determine size and offset of virtualized items.

Returns

  • items: Array<item>
    • item: Object
      • index: 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) => 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.

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Tanner Linsley

💻 🤔 💡 🚧 👀

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

About

⚛️ Hooks for virtualizing scrollable elements in React

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%