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> ) }