You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取react-virtuoso当前的topMostItemIndex以持久化滚动位置?

持久化Virtuoso列表滚动位置:获取并恢复topMostItemIndex

Virtuoso提供了内置方法可以获取当前可视区域最顶部的项索引,结合initialTopMostItemIndex就能实现卸载/重新挂载时的滚动位置持久化,具体步骤如下:

获取当前topMostItemIndex

Virtuoso的ref实例自带getScrollPosition()方法,调用后会返回包含topMostItemIndex的对象,这就是你需要保存的当前滚动位置对应的项索引。

完整实现代码

1. 初始化ref与持久化状态

用React的useRef关联Virtuoso组件,同时从本地存储读取之前保存的索引:

import { useRef, useEffect, useState } from 'react';
import { Virtuoso } from 'react-virtuoso';

function UserList() {
  const virtuosoRef = useRef(null);
  // 从localStorage读取历史索引,默认值为0
  const [savedTopIndex, setSavedTopIndex] = useState(() => {
    return parseInt(localStorage.getItem('virtuosoTopIndex')) || 0;
  });

2. 组件卸载时保存滚动位置

在组件销毁前,调用getScrollPosition()获取当前索引并存入localStorage:

useEffect(() => {
    // 组件卸载时执行保存逻辑
    return () => {
      if (virtuosoRef.current) {
        const scrollPos = virtuosoRef.current.getScrollPosition();
        localStorage.setItem('virtuosoTopIndex', scrollPos.topMostItemIndex.toString());
      }
    };
  }, []);

3. 挂载时恢复滚动位置

将读取到的历史索引传给Virtuoso的initialTopMostItemIndex属性:

return (
    <Virtuoso
      style={{ height: 400 }}
      data={generateUsers(1000)}
      ref={virtuosoRef}
      initialTopMostItemIndex={savedTopIndex}
      itemContent={(index, user) => (
        <div>
          <h4>
            {user.index}. {user.name}
          </h4>
          <div style={{ marginTop: "1rem" }}>{user.description}</div>
        </div>
      )}
    />
  );
}

补充说明

  • 如果你的应用使用全局状态管理工具(如Redux、Zustand),可以将索引存在全局状态中,替代localStorage,适合跨组件共享滚动位置的场景。
  • 若需要更精确的滚动恢复(比如项内的垂直偏移),可以同时保存getScrollPosition()返回的topMostItemOffset,后续用scrollToIndex方法恢复,但仅用initialTopMostItemIndex已能满足大部分场景需求。

内容的提问来源于stack exchange,提问作者Michal Kurz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 01:17:26