react-window
Version:
<img src="https://react-window.vercel.app/og.svg" alt="react-window logo" width="400" height="210" />
315 lines (278 loc) • 19 kB
Markdown
<img src="https://react-window.vercel.app/og.svg" alt="react-window logo" width="400" height="210" />
`react-window` is a component library that helps render large lists of data quickly and without the performance problems that often go along with rendering a lot of data. It's used in a lot of places, from React DevTools to the Replay browser.
## Support
If you like this project there are several ways to support it:
- [Become a GitHub sponsor](https://github.com/sponsors/bvaughn/)
- [Become an Open Collective sponsor](https://opencollective.com/react-window#sponsor)
- or [buy me a coffee](http://givebrian.coffee/)
The following wonderful companies and individuals have sponsored react-window:
<a href="https://opencollective.com/react-window/sponsor/0/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/1/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/2/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/3/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/4/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/5/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/6/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/7/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/8/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/9/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/10/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/10/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/11/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/11/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/12/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/12/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/13/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/13/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/14/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/14/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/15/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/15/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/16/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/16/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/17/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/17/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/18/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/18/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/19/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/19/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/20/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/20/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/21/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/21/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/22/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/22/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/23/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/23/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/24/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/24/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/25/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/25/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/26/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/26/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/27/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/27/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/28/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/28/avatar.svg"></a> <a href="https://opencollective.com/react-window/sponsor/29/website" target="_blank"><img src="https://opencollective.com/react-window/sponsor/29/avatar.svg"></a>
<a href="https://opencollective.com/react-window/backer/0/website" target="_blank"><img src="https://opencollective.com/react-window/backer/0/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/1/website" target="_blank"><img src="https://opencollective.com/react-window/backer/1/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/2/website" target="_blank"><img src="https://opencollective.com/react-window/backer/2/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/3/website" target="_blank"><img src="https://opencollective.com/react-window/backer/3/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/4/website" target="_blank"><img src="https://opencollective.com/react-window/backer/4/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/5/website" target="_blank"><img src="https://opencollective.com/react-window/backer/5/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/6/website" target="_blank"><img src="https://opencollective.com/react-window/backer/6/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/7/website" target="_blank"><img src="https://opencollective.com/react-window/backer/7/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/8/website" target="_blank"><img src="https://opencollective.com/react-window/backer/8/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/9/website" target="_blank"><img src="https://opencollective.com/react-window/backer/9/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/10/website" target="_blank"><img src="https://opencollective.com/react-window/backer/10/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/11/website" target="_blank"><img src="https://opencollective.com/react-window/backer/11/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/12/website" target="_blank"><img src="https://opencollective.com/react-window/backer/12/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/13/website" target="_blank"><img src="https://opencollective.com/react-window/backer/13/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/14/website" target="_blank"><img src="https://opencollective.com/react-window/backer/14/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/15/website" target="_blank"><img src="https://opencollective.com/react-window/backer/15/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/16/website" target="_blank"><img src="https://opencollective.com/react-window/backer/16/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/17/website" target="_blank"><img src="https://opencollective.com/react-window/backer/17/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/18/website" target="_blank"><img src="https://opencollective.com/react-window/backer/18/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/19/website" target="_blank"><img src="https://opencollective.com/react-window/backer/19/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/20/website" target="_blank"><img src="https://opencollective.com/react-window/backer/20/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/21/website" target="_blank"><img src="https://opencollective.com/react-window/backer/21/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/22/website" target="_blank"><img src="https://opencollective.com/react-window/backer/22/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/23/website" target="_blank"><img src="https://opencollective.com/react-window/backer/23/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/24/website" target="_blank"><img src="https://opencollective.com/react-window/backer/24/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/25/website" target="_blank"><img src="https://opencollective.com/react-window/backer/25/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/26/website" target="_blank"><img src="https://opencollective.com/react-window/backer/26/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/27/website" target="_blank"><img src="https://opencollective.com/react-window/backer/27/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/28/website" target="_blank"><img src="https://opencollective.com/react-window/backer/28/avatar.svg"></a> <a href="https://opencollective.com/react-window/backer/29/website" target="_blank"><img src="https://opencollective.com/react-window/backer/29/avatar.svg"></a>
## Installation
Begin by installing the library from NPM:
```sh
npm install react-window
```
## TypeScript types
TypeScript definitions are included within the published `dist` folder
## FAQs
Frequently asked questions can be found [here](https://react-window.vercel.app/common-questions).
## Documentation
Documentation for this project is available at [react-window.vercel.app](https://react-window.vercel.app/); version 1.x documentation can be found at [react-window-v1.vercel.app](https://react-window-v1.vercel.app/).
### List
<!-- List:description:begin -->
Renders data with many rows.
<!-- List:description:end -->
#### Required props
<!-- List:required-props:begin -->
<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>rowComponent</td>
<td><p>React component responsible for rendering a row.</p>
<p>This component will receive an <code>index</code> and <code>style</code> prop by default.
Additionally it will receive prop values passed to <code>rowProps</code>.</p>
<p>ℹ️ The prop types for this component are exported as <code>RowComponentProps</code></p>
</td>
</tr>
<tr>
<td>rowCount</td>
<td><p>Number of items to be rendered in the list.</p>
</td>
</tr>
<tr>
<td>rowHeight</td>
<td><p>Row height; the following formats are supported:</p>
<ul>
<li>number of pixels (number)</li>
<li>percentage of the grid's current height (string)</li>
<li>function that returns the row height (in pixels) given an index and <code>cellProps</code></li>
<li>dynamic row height cache returned by the <code>useDynamicRowHeight</code> hook</li>
</ul>
<p>⚠️ Dynamic row heights are not as efficient as predetermined sizes.
It's recommended to provide your own height values if they can be determined ahead of time.</p>
</td>
</tr>
<tr>
<td>rowProps</td>
<td><p>Additional props to be passed to the row-rendering component.
List will automatically re-render rows when values in this object change.</p>
<p>⚠️ This object must not contain <code>ariaAttributes</code>, <code>index</code>, or <code>style</code> props.</p>
</td>
</tr>
</tbody>
</table>
<!-- List:required-props:end -->
#### Optional props
<!-- List:optional-props:begin -->
<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>className</td>
<td><p>CSS class name.</p>
</td>
</tr>
<tr>
<td>style</td>
<td><p>Optional CSS properties.
The list of rows will fill the height defined by this style.</p>
</td>
</tr>
<tr>
<td>children</td>
<td><p>Additional content to be rendered within the list (above cells).
This property can be used to render things like overlays or tooltips.</p>
</td>
</tr>
<tr>
<td>defaultHeight</td>
<td><p>Default height of list for initial render.
This value is important for server rendering.</p>
</td>
</tr>
<tr>
<td>listRef</td>
<td><p>Ref used to interact with this component's imperative API.</p>
<p>This API has imperative methods for scrolling and a getter for the outermost DOM element.</p>
<p>ℹ️ The <code>useListRef</code> and <code>useListCallbackRef</code> hooks are exported for convenience use in TypeScript projects.</p>
</td>
</tr>
<tr>
<td>onResize</td>
<td><p>Callback notified when the List's outermost HTMLElement resizes.
This may be used to (re)scroll a row into view.</p>
</td>
</tr>
<tr>
<td>onRowsRendered</td>
<td><p>Callback notified when the range of visible rows changes.</p>
</td>
</tr>
<tr>
<td>overscanCount</td>
<td><p>How many additional rows to render outside of the visible area.
This can reduce visual flickering near the edges of a list when scrolling.</p>
</td>
</tr>
<tr>
<td>tagName</td>
<td><p>Can be used to override the root HTML element rendered by the List component.
The default value is "div", meaning that List renders an HTMLDivElement as its root.</p>
<p>⚠️ In most use cases the default ARIA roles are sufficient and this prop is not needed.</p>
</td>
</tr>
</tbody>
</table>
<!-- List:optional-props:end -->
### Grid
<!-- Grid:description:begin -->
Renders data with many rows and columns.
<!-- Grid:description:end -->
#### Required props
<!-- Grid:required-props:begin -->
<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>cellComponent</td>
<td><p>React component responsible for rendering a cell.</p>
<p>This component will receive an <code>index</code> and <code>style</code> prop by default.
Additionally it will receive prop values passed to <code>cellProps</code>.</p>
<p>ℹ️ The prop types for this component are exported as <code>CellComponentProps</code></p>
</td>
</tr>
<tr>
<td>cellProps</td>
<td><p>Additional props to be passed to the cell-rendering component.
Grid will automatically re-render cells when values in this object change.</p>
<p>⚠️ This object must not contain <code>ariaAttributes</code>, <code>columnIndex</code>, <code>rowIndex</code>, or <code>style</code> props.</p>
</td>
</tr>
<tr>
<td>columnCount</td>
<td><p>Number of columns to be rendered in the grid.</p>
</td>
</tr>
<tr>
<td>columnWidth</td>
<td><p>Column width; the following formats are supported:</p>
<ul>
<li>number of pixels (number)</li>
<li>percentage of the grid's current width (string)</li>
<li>function that returns the row width (in pixels) given an index and <code>cellProps</code></li>
</ul>
</td>
</tr>
<tr>
<td>rowCount</td>
<td><p>Number of rows to be rendered in the grid.</p>
</td>
</tr>
<tr>
<td>rowHeight</td>
<td><p>Row height; the following formats are supported:</p>
<ul>
<li>number of pixels (number)</li>
<li>percentage of the grid's current height (string)</li>
<li>function that returns the row height (in pixels) given an index and <code>cellProps</code></li>
</ul>
</td>
</tr>
</tbody>
</table>
<!-- Grid:required-props:end -->
#### Optional props
<!-- Grid:optional-props:begin -->
<table>
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>className</td>
<td><p>CSS class name.</p>
</td>
</tr>
<tr>
<td>dir</td>
<td><p>Indicates the directionality of grid cells.</p>
<p>ℹ️ See HTML <code>dir</code> <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/dir">global attribute</a> for more information.</p>
</td>
</tr>
<tr>
<td>style</td>
<td><p>Optional CSS properties.
The grid of cells will fill the height and width defined by this style.</p>
</td>
</tr>
<tr>
<td>children</td>
<td><p>Additional content to be rendered within the grid (above cells).
This property can be used to render things like overlays or tooltips.</p>
</td>
</tr>
<tr>
<td>defaultHeight</td>
<td><p>Default height of grid for initial render.
This value is important for server rendering.</p>
</td>
</tr>
<tr>
<td>defaultWidth</td>
<td><p>Default width of grid for initial render.
This value is important for server rendering.</p>
</td>
</tr>
<tr>
<td>gridRef</td>
<td><p>Imperative Grid API.</p>
<p>ℹ️ The <code>useGridRef</code> and <code>useGridCallbackRef</code> hooks are exported for convenience use in TypeScript projects.</p>
</td>
</tr>
<tr>
<td>onCellsRendered</td>
<td><p>Callback notified when the range of rendered cells changes.</p>
</td>
</tr>
<tr>
<td>onResize</td>
<td><p>Callback notified when the Grid's outermost HTMLElement resizes.
This may be used to (re)scroll a cell into view.</p>
</td>
</tr>
<tr>
<td>overscanCount</td>
<td><p>How many additional rows/columns to render outside of the visible area.
This can reduce visual flickering near the edges of a grid when scrolling.</p>
</td>
</tr>
<tr>
<td>tagName</td>
<td><p>Can be used to override the root HTML element rendered by the List component.
The default value is "div", meaning that List renders an HTMLDivElement as its root.</p>
<p>⚠️ In most use cases the default ARIA roles are sufficient and this prop is not needed.</p>
</td>
</tr>
</tbody>
</table>
<!-- Grid:optional-props:end -->