File size: 1,310 Bytes
4c1e4ec |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
import React, { useState, useMemo, useRef, useEffect } from 'react';
import { FixedSizeList as List } from 'react-window';
interface VirtualGameListProps {
games: any[];
itemHeight: number;
height: number;
width: number;
renderItem: (props: { index: number; style: any; data: any[] }) => React.ReactElement;
}
export const VirtualGameList: React.FC<VirtualGameListProps> = ({
games,
itemHeight,
height,
width,
renderItem
}) => {
const listRef = useRef<List>(null);
return (
<List
ref={listRef}
height={height}
width={width}
itemCount={games.length}
itemSize={itemHeight}
itemData={games}
overscanCount={5} // Renderizar 5 itens extras para smoother scrolling
>
{renderItem}
</List>
);
};
// Hook para detectar se o elemento está visível
export const useInView = (ref: React.RefObject<HTMLElement>, threshold = 0.1) => {
const [isInView, setIsInView] = useState(false);
useEffect(() => {
const element = ref.current;
if (!element) return;
const observer = new IntersectionObserver(
([entry]) => {
setIsInView(entry.isIntersecting);
},
{ threshold }
);
observer.observe(element);
return () => observer.disconnect();
}, [ref, threshold]);
return isInView;
};
|