Skip to content
kaskaid

Imperative Scrolling

Jump to an item by index

Sometimes the grid has to move on its own — restoring a position after navigation, jumping to a search hit, or stepping through results. Both flavors expose the same scrollToIndex(index, options), a thin forward to TanStack Virtual's own method.

options.align is 'start' | 'center' | 'end' | 'auto' (default 'auto': nearest edge, and a no-op if the item is already visible) and options.behavior is 'auto' | 'smooth'.

With the component

You don't have to drop to useMasonry for imperative control. Pass a ref typed as MasonryHandle to reach scrollToIndex — and the virtualizer escape hatch — from the component:

const ref = useRef<MasonryHandle>(null);
 
<>
  <button onClick={() => ref.current?.scrollToIndex(5, { align: 'center' })}>Jump to 5</button>
  <Masonry ref={ref} data={data} estimateSize={estimate} renderItem={renderItem} />
</>;

See <Masonry /> › ref for the full runnable example and the handle's surface. Reach for the hook instead only when you also need a custom element structure.

With the hook

useMasonry returns scrollToIndex directly. It is referentially stable across renders, so it is safe to list in an effect's dependency array:

import {  } from 'kaskaid';
 
const  = [200, 600, 200, 400, 100, 600, 200, 400, 100, 600];
 
function () {
  const { , , ,  } = ({
    : ,
    : () => 400,
  });
 
  return (
    <>
      < ={() => (7, { : 'center' })}>Jump to item 7</>
      < {...}>
        {.(() => (
          < ={.} {...()}>
            < ={{ : [.] }}>{.}</>
          </>
        ))}
      </>
    </>
  );
}

Beyond scrollToIndex

For imperative APIs beyond scrollToIndexscrollToOffset, measure — reach through to the underlying TanStack virtualizer. It is exposed as virtualizer on both the hook return and MasonryHandle.

Reference