1. 虚拟化列表 (List)
// 1. 虚拟化列表 (List)
import { List } from 'react-virtualized';
import 'react-virtualized/styles.css'; // 只导入一次样式
// 示例数据
const list = Array(1000).fill().map((_, index) => ({
id: index,
name: `Item ${index}`,
description: `This is item number ${index} in the list`
}));
function Index() {
const rowRenderer = ({ index, key, style }) => {
const item = list[index];
return (
<div key={key} style={style} className="list-item">
<h3>{item.name}</h3>
<p>{item.description}</p>
</div>
);
};
return (
<List
width={600} // 列表宽度
height={400} // 列表高度
rowCount={list.length} // 总行数
rowHeight={80} // 每行高度
rowRenderer={rowRenderer} // 行渲染函数
overscanRowCount={5} // 预渲染的行数
/>
)
}
export default Index;
2. 可变高度列表 (CellMeasurer)
// 2. 可变高度列表 (CellMeasurer)
import { List, CellMeasurer, CellMeasurerCache } from 'react-virtualized';
import 'react-virtualized/styles.css';
// 可变高度数据
const variableData = Array(500).fill().map((_, index) => ({
id: index,
title: `Item ${index}`,
content: `This is item ${index}. `.repeat(Math.floor(Math.random() * 10) + 1)
}));
function Index() {
// 创建测量缓存
const cache = new CellMeasurerCache({
defaultHeight: 60,
fixedWidth: true
});
const rowRenderer = ({ index, key, parent, style }) => {
const item = variableData[index];
return (
<CellMeasurer
key={key}
cache={cache}
parent={parent}
columnIndex={0}
rowIndex={index}
>
<div style={style} className="variable-item">
<h3>{item.title}</h3>
<p>{item.content}</p>
</div>
</CellMeasurer>
);
};
return (
<List
width={600} // 列表宽度
height={400} // 列表高度
deferredMeasurementCache={cache}
rowHeight={cache.rowHeight} // 每行高度
rowCount={variableData.length} // 总行数
rowRenderer={rowRenderer} // 行渲染函数
overscanRowCount={3} // 预渲染的行数
/>
)
}
export default Index;
3. 无限加载列表 - 高度固定
// 3. 无限加载列表 - 高度固定
import React, { useState } from 'react';
import { List, AutoSizer } from 'react-virtualized';
import 'react-virtualized/styles.css';
function InfiniteLoadingList() {
const [items, setItems] = useState(
Array(50).fill().map((_, i) => ({ id: i, name: `Item ${i}` }))
);
const [loading, setLoading] = useState(false);
const loadMoreItems = () => {
if (loading) return;
setLoading(true);
// 模拟API调用
setTimeout(() => {
const newItems = Array(50).fill().map((_, i) => ({
id: items.length + i,
name: `Item ${items.length + i}`
}));
setItems(prev => [...prev, ...newItems]);
setLoading(false);
}, 1000);
};
const isRowLoaded = ({ index }) => index < items.length;
const rowRenderer = ({ index, key, style }) => {
if (!isRowLoaded({ index })) {
return (
<div key={key} style={style} className="loading-row">
Loading...
</div>
);
}
const item = items[index];
return (
<div key={key} style={style} className="list-item">
{item.name}
</div>
);
};
const onRowsRendered = ({ stopIndex }) => {
if (stopIndex >= items.length - 10 && !loading) {
loadMoreItems();
}
};
return (
<div style={{ height: '500px', width: '100%' }}>
<AutoSizer>
{({ width, height }) => (
<List
width={width}
height={height}
rowCount={items.length + 1} // +1 for loading row
rowHeight={50}
rowRenderer={rowRenderer}
onRowsRendered={onRowsRendered}
overscanRowCount={5}
/>
)}
</AutoSizer>
{loading && <div className="loading-indicator">Loading more items...</div>}
</div>
);
}
export default InfiniteLoadingList;
4. 无限加载列表 - 高度不固定
// 4. 无限加载列表 - 高度不固定