如何获取Material-UI表格滚动位置并实现返回页面时自动恢复滚动位置
Material-UI v4 虚拟表格滚动位置记忆与恢复实现方案
核心逻辑
MUI v4官方提供的虚拟表格基于react-window的FixedSizeList实现,只需要拿到列表实例的引用,即可直接获取滚动状态、调用滚动API完成需求。
实现步骤
1. 绑定列表实例引用
先定义ref挂载到内部的FixedSizeList组件上,如果是二次封装的虚拟表格,需要通过forwardRef透传ref到内部列表:
import { useRef } from 'react'; import { FixedSizeList } from 'react-window'; // 组件内定义ref const virtualListRef = useRef(null); // 挂载到FixedSizeList上 <FixedSizeList ref={virtualListRef} height={400} itemCount={1000} itemSize={35} width="100%" > {/* 原有行渲染逻辑 */} </FixedSizeList>
2. 实时存储滚动位置
通过FixedSizeList的onScroll回调获取滚动偏移量,存储到sessionStorage/全局状态中,建议key加上页面唯一标识避免多页面冲突:
const handleListScroll = ({ scrollOffset, visibleStartIndex }) => { // 方式1:存储像素滚动偏移 sessionStorage.setItem('userList_scroll_offset', String(scrollOffset)); // 方式2:存储可见区域第一行的索引,适配性更强 // sessionStorage.setItem('userList_scroll_index', String(visibleStartIndex)); }; // 给FixedSizeList加上onScroll回调 <FixedSizeList // 其他原有props onScroll={handleListScroll} />
3. 页面返回时恢复滚动位置
组件挂载后读取存储的滚动位置,调用列表实例的滚动API恢复位置:
import { useEffect } from 'react'; useEffect(() => { // 对应方式1的恢复逻辑 const savedOffset = sessionStorage.getItem('userList_scroll_offset'); if (savedOffset && virtualListRef.current) { virtualListRef.current.scrollTo(Number(savedOffset)); } // 对应方式2的恢复逻辑 // const savedIndex = sessionStorage.getItem('userList_scroll_index'); // if (savedIndex && virtualListRef.current) { // virtualListRef.current.scrollToItem(Number(savedIndex), 'start'); // } }, []);
注意事项
- 若路由跳转后不需要长期保留位置,可在组件卸载时清理存储的位置数据
- 按行索引定位的适配性更好,不会出现滚动后半行显示的问题,建议优先使用
scrollToItem方案 - 必须保证ref绑定到了真实的
FixedSizeList实例,否则滚动API会调用失败
内容的提问来源于stack exchange,提问作者greatertomi
相关产品推荐
相关产品推荐

