簡介
React Window 是一個高效的 React 組件庫,專為渲染大數據列表和表格數據而設計。它通過”虛擬化”技術(也稱為”窗口化”或”列表虛擬化”)解決了在 React 應用中渲染大量數據時的性能問題。與傳統方法不同,React Window 只渲染用戶當前可見的元素,而不是整個列表,從而顯著提高了渲染性能和內存使用效率。
主要特性
- 高性能渲染:只渲染可視區域內的元素,大幅提升性能
- 靈活的布局:支持固定大小和可變大小的列表項
- 多種列表類型:支持垂直列表、水平列表和網格布局
- 輕量級:體積小,依賴少,易于集成
- 滾動優化:平滑的滾動體驗,支持自動滾動到指定位置
- TypeScript 支持:完整的類型定義
安裝方法
npm install react-window
# 或
yarn add react-window
使用示例
固定大小的列表
import { FixedSizeList } from "react-window";const Example = () => {const items = Array(1000).fill().map((_, index) => `Item ${index}`);const Row = ({ index, style }) => (<divstyle={style}className="px-4 py-2 border-b border-gray-200 hover:bg-gray-50 transition-colors cursor-pointer">{items[index]}</div>);return (<div className="flex justify-center items-center min-h-screen bg-gray-100"><div className="bg-white rounded-lg shadow-lg overflow-hidden"><FixedSizeListheight={400}width={300}itemCount={items.length}itemSize={40}className="scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-gray-100">{Row}</FixedSizeList></div></div>);
};export default Example;
可變大小的列表
import { VariableSizeList } from "react-window";const Example = () => {const items = Array(1000).fill().map((_, index) => `Item ${index}`);// 根據索引返回不同的高度const getItemSize = (index) => {return 35 + (index % 3) * 15; // 35, 50, 65 像素的交替高度};const Row = ({ index, style }) => (<divstyle={style}className={`px-4 py-2 ${index % 2 === 0 ? "bg-gray-50" : "bg-white"}hover:bg-blue-50 transition-colorsborder-b border-gray-200cursor-pointerflex items-centertext-gray-700hover:text-blue-600`}><span className="mr-3 text-sm font-medium">{index + 1}.</span>{items[index]}</div>);return (<div className="flex justify-center items-center min-h-screen bg-gray-100"><div className="border border-gray-200 rounded-md overflow-hidden"><VariableSizeListheight={400}width={300}itemCount={items.length}itemSize={getItemSize}className="scrollbar-thin scrollbar-thumb-gray-300 scrollbar-track-gray-100">{Row}</VariableSizeList></div></div>);
};export default Example;
網格布局
import { FixedSizeGrid } from "react-window";const Example = () => {const Cell = ({ columnIndex, rowIndex, style }) => (<divstyle={style}className="border border-gray-200 p-2 bg-white hover:bg-gray-50 transition-colors duration-200 flex items-center justify-center text-sm text-gray-600">Item {rowIndex},{columnIndex}</div>);return (<div className="flex justify-center items-center min-h-screen bg-gray-100"><FixedSizeGridcolumnCount={100}columnWidth={100}height={400}rowCount={100}rowHeight={35}width={300}className="bg-white rounded border border-gray-300">{Cell}</FixedSizeGrid></div>);
};export default Example;
高級用法
結合 react-virtualized-auto-sizer 自適應容器大小
import { FixedSizeList } from "react-window";
import AutoSizer from "react-virtualized-auto-sizer";const Example = () => {const items = Array(1000).fill().map((_, index) => `Item ${index}`);const Row = ({ index, style }) => (<divstyle={style}className="px-4 py-2 border-b border-gray-200 hover:bg-gray-50 transition-colors duration-200"><span className="text-gray-800 font-medium">{items[index]}</span></div>);return (<div className="h-screen w-full bg-white shadow-lg rounded-lg overflow-hidden mt-7"><AutoSizer>{({ height, width }) => (<FixedSizeListclassName="scrollbar-thin scrollbar-thumb-gray-400 scrollbar-track-gray-100"height={height - 64} // Subtract header heightwidth={width}itemCount={items.length}itemSize={45}>{Row}</FixedSizeList>)}</AutoSizer></div>);
};export default Example;
使用 useRef 和 scrollToItem 方法
import { useRef } from "react";
import { FixedSizeList } from "react-window";const Example = () => {const listRef = useRef();const items = Array(1000).fill().map((_, index) => `Item ${index}`);const scrollToItem = (index) => {listRef.current.scrollToItem(index, "center");};return (<div className="p-6 max-w-md mx-auto bg-white rounded-xl"><div className="space-x-4 mb-6"><buttononClick={() => scrollToItem(50)}className="bg-blue-500 hover:bg-blue-600 text-white font-semibold py-2 px-4 rounded-lg transition duration-200">滾動到第50項</button><buttononClick={() => scrollToItem(300)}className="bg-green-500 hover:bg-green-600 text-white font-semibold py-2 px-4 rounded-lg transition duration-200">滾動到第300項</button></div><div className="border rounded-lg overflow-hidden"><FixedSizeListref={listRef}height={620}width={400}itemCount={items.length}itemSize={35}className="scrollbar-thin scrollbar-thumb-gray-400 scrollbar-track-gray-100">{({ index, style }) => (<divstyle={style}className="px-4 py-2 hover:bg-gray-100 transition-colors duration-150 border-b border-gray-100">{items[index]}</div>)}</FixedSizeList></div></div>);
};export default Example;
性能優化建議
- 使用 memoization:對列表項組件使用 React.memo 減少不必要的重渲染
- 避免內聯樣式:盡量使用 CSS 類而不是內聯樣式
- 合理設置 overscanCount:適當增加預渲染的項目數量,提升滾動體驗
- 使用 isScrolling 參數:在快速滾動時可以顯示占位符內容
與其他庫的比較
- react-virtualized:React Window 是 react-virtualized 的輕量級替代品,API 更簡潔,體積更小
- react-virtual:更現代的虛擬化庫,使用 hooks API,但 React Window 更成熟穩定
- 原生實現:相比自己實現虛擬滾動,React Window 提供了更完善的功能和更好的性能
?react-window大型列表和表格數據渲染組件之虛擬滾動 - 高質量源碼分享平臺-免費下載各類網站源碼與模板及前沿技術分享