@jason12306/react-async-virtual-scroll
Version:
High-performance asynchronous virtual scroll component for react with dynamic height support and optimized rendering for large datasets
162 lines (124 loc) • 5.84 kB
Markdown
# async-virtual-scroll - React Asynchronous Virtual Scroll Component
> High-performance virtual scroll component supporting dynamic height rendering, optimized for large data list display
[简体中文](https://github.com/Jason12306/react-async-virtual-scroll/blob/main/README-ZH_CN.md)
[vue Version](https://github.com/Jason12306/vue-async-virtual-scroll)
## Features
- 🚀 Efficient rendering of massive data
- 📏 Supports fixed height and dynamic height
- 🔍 Automatically calculates visible area content
- 🔄 Built-in scroll optimization and buffer mechanism
- ⏳ Smart loading state management
- 🔧 Highly customizable
## Installation & Usage
### Installation
```bash
npm install @jason12306/react-async-virtual-scroll
```
### Basic Usage
```tsx
import React, { useState } from 'react'
import AsyncVirtualScroll from '@jason12306/react-async-virtual-scroll'
import '@jason12306/react-async-virtual-scroll/react-async-virtual-scroll.css'
const App = () => {
const [enabled, setEnabled] = useState(true)
const items = Array.from({ length: 500 }, (_, i) => ({
id: i + 1,
text: `Item ${i + 1}`,
color: (i + 1) % 2 ? '#e0f7fa' : '#fffde7',
}))
return (
<div style={{ height: 500, border: '1px solid #ddd', overflow: 'auto' }}>
<AsyncVirtualScroll
value={enabled}
data={items}
itemSize={60}
keyField="id"
>
{(item, index, dataUid) => (
<div
key={item.id}
data-uid={dataUid}
style={{
height: 60,
lineHeight: '60px',
padding: '0 16px',
borderBottom: '1px solid #eee',
backgroundColor: item.color,
boxSizing: 'border-box',
}}
>
{item.id}. {item.text}
</div>
)}
</AsyncVirtualScroll>
</div>
)
}
export default App
```
## Props Configuration
| Name | Type | Required | Default | Description |
| ----------- | ---------------- | --------------------------- | ---------- | ----------------------------------------------------------------- |
| value | Boolean | Yes | false | Controls whether virtual scroll is enabled (controlled mode) |
| ban | Boolean | No | false | Disables virtual scroll (suitable for small datasets) |
| itemSize | Number | Required for fixed height | undefined | Item height in fixed height mode (px) |
| minItemSize | Number | Required for dynamic height | undefined | Minimum item height in dynamic height mode (px) |
| data | Array | Yes | [] | Data array to render |
| buffer | [number, number] | No | [200, 200] | Buffer size [top buffer, bottom buffer] (px) |
| keyField | String | No | 'id' | Unique identifier field name for data items |
| dataUid | String | No | 'data-uid' | DOM attribute name for storing unique data identifier |
| viewNum | Number | No | 1 | Initial minimum visible item count (for estimation) |
| children | Function | Yes | | Render function for each item (item, index, dataUid) => ReactNode |
## children Render Function Parameters
| Parameter | Type | Description |
| --------- | ------ | --------------------------------- |
| item | Object | Current data item |
| index | Number | Current item index |
| dataUid | String | Unique identifier attribute value |
## Usage Scenarios
### 1. Fixed Height Mode
When all items have the same height, use fixed height mode:
```tsx
<AsyncVirtualScroll value={enabled} data={largeList} itemSize={60}>
{(item) => <div>{item.text}</div>}
</AsyncVirtualScroll>
```
### 2. Dynamic Height Mode
When items have varying heights, use dynamic height mode:
```tsx
<AsyncVirtualScroll value={enabled} data={varyingHeightList} minItemSize={40}>
{(item) => <div>{item.text}</div>}
</AsyncVirtualScroll>
```
### 3. Disable Virtual Scroll for Small Datasets
```tsx
<AsyncVirtualScroll data={list} ban={list.length < 100}>
{(item) => <div>{item.text}</div>}
</AsyncVirtualScroll>
```
### 4. Custom Buffer
```tsx
<AsyncVirtualScroll data={list} buffer={[150, 300]}>
{(item) => <div>{item.text}</div>}
</AsyncVirtualScroll>
```
## Notes
1. **The `value` prop is required (controlled mode)**
2. **Dynamic height mode requires `minItemSize` for initial height estimation**
3. **Performance Recommendations**
- Prefer `itemSize` for fixed height
- Set a reasonable `buffer` for better experience
- Avoid complex calculations in `children`
4. **Data changes automatically trigger layout updates**
## Why Virtual Scroll?
Traditional rendering of large data lists causes:
- **High memory usage**: Thousands of DOM nodes
- **Low rendering performance**: Frequent browser layout and repaint
- **Interaction lag**: Obvious delays in scrolling and operations
**Asynchronous Virtual Scroll** addresses these issues by:
- 🚀 **On-demand rendering**: Only renders visible area
- ⏱ **Asynchronous calculation**: Uses IntersectionObserver to detect visibility
- 🔄 **Smart buffering**: Preloads buffer elements for smoother scrolling
- 📊 **Height caching**: Records rendered item heights to avoid recalculation
## License
MIT License