react-window

GitHub

React components for efficiently rendering large lists and tabular data

17,173 stars TypeScript Markdown CodeWiki
AI Prompts & Endpoints
CodeWiki Knowledge Base

Repository: bvaughn/react-window


Stars: 17146

README.md

<img src="https://react-window.vercel.app/og.png" 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
- Become an Open Collective sponsor
- or buy me a 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.

Documentation

Documentation for this project is available at react-window.vercel.app; version 1.x documentation can be found at 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&#39;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&#39;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&#39;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&#39;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 &quot;div&quot;, 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.

â„šī¸ Unlike List rows, Grid cell sizes must be known ahead of time.
Either static sizes or something that can be derived (from the data in CellProps) without rendering.
<!-- 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&#39;s current width (string)</li>
<li>function that returns the column 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&#39;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&#39;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 &quot;div&quot;, 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 -->