0

I'm trying to implement a virtualisation component with reactjs.

In order to fill the empty top and bottom gap I used an empty div with dynamic height which depends on the scroll position.

      <div style={{ height: topPlaceholderHeight }} />
         {visibleItems.map(renderItem)}
      <div style={{ height: bottomPlaceholderHeight }} />

When the user scrolls > a scroll event is triggered > placeholderHeight is updated > triggers an other scroll event => infinite loop that leads to an auto scroll to the bottom

  const [start, setStart] = useState(0);
  const [end, setEnd] = useState(0);
  const [scrollTop, setScrollTop] = useState(0);
  const parentRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const listElement = parentRef.current;
    if (!listElement) return;

    const itemsPerPage = Math.ceil(listElement.offsetHeight / itemHeight) + 2;

    const newStart = Math.max(0, Math.floor(scrollTop / itemHeight) - 1);
    const newEnd = Math.min(items.length, newStart + itemsPerPage);

    setStart(newStart);
    setEnd(newEnd);
  }, [items, itemHeight, scrollTop]);

  useEffect(() => {
    const listElement = parentRef.current;
    if (!listElement) return;

    const scrollHandler = () => {
      setScrollTop(listElement.scrollTop);
    };

    listElement.addEventListener("scroll", scrollHandler);
    return () => listElement.removeEventListener("scroll", scrollHandler);
  }, [parentRef]);

Code sandbox

Any suggestions for solving this problem ?

0 Answers0