PrimeReact中DataTable集成DataScroller(虚拟滚动)实现示例请求
Integrating PrimeReact DataScroller with DataTable for Virtual Scroll
Hey there! Let me walk you through how to integrate PrimeReact's DataScroller with your existing DataTable to get that smooth virtual-scroll experience. I’ll break this down with a complete, adaptable example and explain the key bits so you understand what’s going on.
First, let’s start with a full functional component example. This assumes you already have PrimeReact set up in your project (since you’ve got DataTable working already):
import { useState, useEffect } from 'react'; import { DataScroller } from 'primereact/datascroller'; import { DataTable } from 'primereact/datatable'; import { Column } from 'primereact/column'; import { ProgressSpinner } from 'primereact/progressspinner'; const VirtualScrollDataTable = () => { // State to hold loaded data, loading status, and total record count const [tableItems, setTableItems] = useState([]); const [isLoading, setIsLoading] = useState(false); const [totalRecords, setTotalRecords] = useState(150); // Replace with actual total from your API // Simulate async data fetch (replace this with your real API call) const loadData = (event) => { setIsLoading(true); // Simulate API delay setTimeout(() => { // Generate mock data matching your schema const newBatch = Array.from({ length: event.rows }, (_, idx) => ({ id: event.first + idx + 1, productName: `Wireless Headset ${event.first + idx + 1}`, brand: ['Sony', 'Bose', 'Sennheiser'][Math.floor(Math.random() * 3)], price: Math.floor(Math.random() * 500) + 99 })); // Update state: replace for first page, append for subsequent pages setTableItems(prev => event.first === 0 ? newBatch : [...prev, ...newBatch]); setIsLoading(false); }, 800); }; // Load initial data on component mount useEffect(() => { loadData({ first: 0, rows: 25 }); }, []); return ( <div className="p-4 max-w-4xl mx-auto"> <h2 className="text-xl font-semibold mb-4">Product Catalog (Virtual Scroll)</h2> <DataScroller value={tableItems} rows={25} lazy virtualScroll itemSize={55} // Critical: Match this to your table row's actual height in pixels onLazyLoad={loadData} totalRecords={totalRecords} loading={isLoading} loader={<div className="flex justify-center py-4"><ProgressSpinner /></div>} className="h-[600px] overflow-auto" // Set fixed height for scroll container > <DataTable value={tableItems} scrollable scrollHeight="100%"> <Column field="id" header="ID" className="w-16" /> <Column field="productName" header="Product Name" className="w-48" /> <Column field="brand" header="Brand" className="w-32" /> <Column field="price" header="Price" className="w-24" /> </DataTable> </DataScroller> </div> ); }; export default VirtualScrollDataTable;
Key Details to Note:
- Virtual Scroll Setup: The
virtualScrollprop on DataScroller enables the virtualization behavior—only rows in the visible viewport get rendered, which is great for large datasets. - Item Size: The
itemSizeprop is mandatory here. You need to set it to the exact pixel height of your table rows. If this doesn’t match, you’ll see weird scrolling glitches or missing rows. - Lazy Loading: The
lazyprop andonLazyLoadhandler work together to fetch data only when the user scrolls near the bottom. Theeventparameter passed toloadDatagives youfirst(starting index) androws(number of items to load), which you’ll use to query your backend. - DataTable Configuration: Set
scrollabletotrueandscrollHeightto"100%"so the table fills the entire DataScroller container. - Loading State: The
loaderprop lets you show a spinner (or any component) while data is being fetched, improving user experience.
Quick Tips for Your Project:
- Replace Mock Data: Swap the
setTimeoutinloadDatawith your actual API call. Make sure to passfirstandrowsas pagination parameters, and updatetotalRecordswith the value returned from your backend. - Adjust Styling: Tweak the
classNameon DataScroller to set your desired container height. You can also adjust column widths and row styling to match your app’s design. - Test Row Height: Double-check that
itemSizematches your table row’s actual height (use browser dev tools to measure if needed). This is crucial for smooth virtual scrolling.
内容的提问来源于stack exchange,提问作者Vicky




