Implement a Virtual Scroll List
3 minintermediatereactcodingvirtualscrolllist
Quick Answer
Design a component that efficiently renders large lists by only rendering visible items.
Detailed Answer
Implement a Virtual Scroll List
Design a component that efficiently renders large lists by only rendering visible items.
Solution:
interface VirtualListProps<T> {
items: T[];
itemHeight: number;
containerHeight: number;
renderItem: (item: T, index: number) => React.ReactNode;
}
function VirtualList<T>({ items, itemHeight, containerHeight, renderItem }: VirtualListProps<T>) {
const [scrollTop, setScrollTop] = useState(0);
const containerRef = useRef<HTMLDivElement>(null);
const visibleStart = Math.floor(scrollTop / itemHeight);
const visibleEnd = Math.min(
visibleStart + Math.ceil(containerHeight / itemHeight) + 1,
items.length
);
const visibleItems = items.slice(visibleStart, visibleEnd);
const totalHeight = items.length * itemHeight;
const offsetY = visibleStart * itemHeight;
return (
<div
ref={containerRef}
style={{ height: containerHeight, overflow: 'auto' }}
onScroll={(e) => setScrollTop(e.currentTarget.scrollTop)}
>
<div style={{ height: totalHeight, position: 'relative' }}>
<div style={{ transform: `translateY(${offsetY}px)` }}>
{visibleItems.map((item, index) => (
<div key={visibleStart + index} style={{ height: itemHeight }}>
{renderItem(item, visibleStart + index)}
</div>
))}
</div>
</div>
</div>
);
}
// Usage
const LargeList = () => {
const items = Array.from({ length: 10000 }, (_, i) => ({ id: i, name: `Item ${i}` }));
return (
<VirtualList
items={items}
itemHeight={50}
containerHeight={400}
renderItem={(item) => <div>{item.name}</div>}
/>
);
};