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

React中基于react-custom-scrollbars实现列滚动位置本地存储与恢复

解决react-custom-scrollbars列滚动位置的本地存储与恢复问题

针对多列独立滚动条的场景,我们可以通过为每列分配唯一标识、监听滚动事件存储位置、组件挂载时恢复位置这三个核心步骤实现需求。以下是可直接运行的修改方案:

核心实现思路

  • 给每个滚动列分配唯一ID,用于区分localStorage中的存储键
  • 通过useRef获取Scrollbars组件实例,以便调用滚动控制方法
  • 监听onScroll事件,实时将滚动位置存入localStorage
  • 组件挂载时,从localStorage读取对应列的保存位置并恢复

修改后的完整代码

import "./styles.css";
import Scrollbars from "react-custom-scrollbars";
import { useEffect, useRef } from "react";

// 模拟多列数据,为每列添加唯一id
const COLUMN_DATA = [
  { id: 1, items: Array.from({ length: 50 }, (_, i) => `Item ${i + 1}`) },
  { id: 2, items: Array.from({ length: 50 }, (_, i) => `Element ${i + 1}`) },
  { id: 3, items: Array.from({ length: 50 }, (_, i) => `Entry ${i + 1}`) }
];

export default function App() {
  return (
    <div className="App">
      <div className="columns-container">
        {COLUMN_DATA.map((column) => (
          <ScrollableColumn key={column.id} column={column} />
        ))}
      </div>
    </div>
  );
}

// 抽离独立的滚动列组件,便于复用和维护
function ScrollableColumn({ column }) {
  const scrollRef = useRef(null);
  // 生成唯一的localStorage键名
  const storageKey = `scroll-position-${column.id}`;

  useEffect(() => {
    // 组件挂载时恢复滚动位置
    const savedTop = localStorage.getItem(storageKey);
    if (savedTop && scrollRef.current) {
      // 将存储的字符串转为数字,调用scrollTop方法恢复位置
      scrollRef.current.scrollTop(parseInt(savedTop, 10));
    }
  }, [storageKey]);

  // 滚动事件处理函数:实时保存滚动位置
  const handleScroll = () => {
    if (scrollRef.current) {
      const { top } = scrollRef.current.getValues();
      localStorage.setItem(storageKey, top.toString());
    }
  };

  return (
    <div className="column">
      <Scrollbars
        ref={scrollRef}
        onScroll={handleScroll}
        style={{ height: "400px", width: "250px" }}
      >
        <div className="column-content">
          {column.items.map((item, idx) => (
            <div key={idx} className="item">
              {item}
            </div>
          ))}
        </div>
      </Scrollbars>
    </div>
  );
}

关键细节说明

  1. 唯一标识与存储键:通过column.id生成唯一的storageKey,避免多列滚动位置互相覆盖
  2. Ref实例获取:必须通过useRef绑定到Scrollbars组件,才能调用其内置的scrollTop和getValues方法
  3. 滚动事件监听:onScroll会在滚动过程中触发,实时获取当前滚动的top值并存入localStorage
  4. 挂载时恢复:在useEffect中(依赖数组仅包含storageKey),组件挂载完成后读取存储值并恢复位置,确保DOM已渲染完成

常见失效原因排查

如果之前的实现未生效,可能是以下问题导致:

  • 未正确获取Scrollbars组件实例,无法调用滚动控制方法
  • 多列使用了相同的存储键,导致位置被覆盖
  • 在组件未挂载完成时调用了scrollTop,此时DOM还未初始化

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 18:22:44