Scroll to Index

The Virtuoso component exposes an imperative scrollToIndex method, which scrolls the item at the specified index into view. As an optional configuration, the method accepts align: 'start' | 'center' | 'end' and behavior: 'smooth'.

Warning: Using smooth scrolling over many items can kill performance and potentially clash with loading strategies.

import { Virtuoso } from 'react-virtuoso'
import { generateUsers, avatar, avatarPlaceholder } from './data'
import { useState, useMemo, useRef } from 'react'

export default function App() {
  const [align, setAlign] = useState("start");
  const [behavior, setBehavior] = useState("auto");
  const virtuoso = useRef(null);
  const users = useMemo(() => generateUsers(1000), []);
  return (
    <div>
      <ul className="knobs">
        <li>
          <button
            onClick={() => {
              virtuoso.current.scrollToIndex({
                index: 0,
                align,
                behavior
              });
              return false;
            }}
          >
            Scroll To 1
          </button>
        </li>
        <li>
          <button
            onClick={() => {
              virtuoso.current.scrollToIndex({
                index: 499,
                align,
                behavior
              });
              return false;
            }}
          >
            Scroll To 500
          </button>
        </li>
        <li>
          <button
            onClick={() => {
              virtuoso.current.scrollToIndex({
                index: 999,
                align,
                behavior
              });
              return false;
            }}
          >
            Scroll To 1000
          </button>
        </li>
        <li>
          <label>
            Align:
            <select value={align} onChange={(e) => setAlign(e.target.value)}>
              <option value="start">Start</option>
              <option value="center">Center</option>
              <option value="end">End</option>
            </select>
          </label>
        </li>
        <li>
          <label>
            Behavior:
            <select value={behavior} onChange={(e) => setBehavior(e.target.value)}>
              <option value="auto">Instant (auto)</option>
              <option value="smooth">Smooth</option>
            </select>
          </label>
        </li>
      </ul>

      <div style={{height: 600}}>
        <Virtuoso
          data={users}
          ref={virtuoso}
          itemContent={(index, user) => {
            return (
              <div
                style={{
                  backgroundColor: user.bgColor,
                  padding: "1rem 0",
                }}
              >
                <div style={{ float: "left", margin: "1rem" }}>{avatar()}</div>

                <h4>{user.index}. {user.name}</h4>

                {user.longText}
              </div>
            );
          }}
        />
      </div>
    </div>
  )
}