Blog>
Snippets

Synchronizing Scroll Positions Across Lists

Demonstrate a method for synchronizing scroll positions between two or more virtualized lists using TanStack Virtual.
const [scrollOffset, setScrollOffset] = useState(0);
Initialize state to keep track of the scroll position.
const onScroll = ({ scrollOffset }) => {
  setScrollOffset(scrollOffset);
};
Define an onScroll function that updates the scrollOffset state based on the current scroll position of the list.
const list1Ref = useRef();
const list2Ref = useRef();
Create refs for each list to access their instances directly.
useEffect(() => {
  if (list1Ref.current) {
    list1Ref.current.scrollTo(scrollOffset);
  }
  if (list2Ref.current) {
    list2Ref.current.scrollTo(scrollOffset);
  }
}, [scrollOffset]);
Use an effect to synchronize the scroll position between the lists. Whenever scrollOffset changes, both lists scroll to that position.
<FixedSizeList
  height={500}
  itemCount={items.length}
  itemSize={35}
  width={300}
  onScroll={onScroll}
  ref={list1Ref}
>
  {({ index, style }) => <div style={style}>{items[index]}</div>}
</FixedSizeList>
The first virtualized list using FixedSizeList from react-window. It's wired up to update scrollOffset on scroll.
<FixedSizeList
  height={500}
  itemCount={items.length}
  itemSize={35}
  width={300}
  itemData={items}
  ref={list2Ref}
  style={{ marginTop: '20px' }}
>
  {({ index, style }) => <div style={style}>{items[index]}</div>}
</FixedSizeList>
The second virtualized list. It's automatically synced with the first list's scroll position through the useEffect.