Skip to content

React API

@seamless-scroll/react 提供了React组件和Hook,用于在React应用中实现无缝滚动效果。

组件

SeamlessScroll 组件

SeamlessScroll 组件现在支持泛型类型 <T>,使数据项获得完整的类型推断。当您传入数据数组时,TypeScript 会自动推断 item 的类型。

属性

属性名类型默认值说明
directionString'vertical'滚动方向,可选值:'vertical'(垂直)或 'horizontal'(水平)
speedNumber50滚动速度(像素/秒)
durationNumber500每次滚动动画的持续时间(毫秒)
pauseTimeNumber2000每次滚动后的暂停时间(毫秒)
hoverPauseBooleantrue是否在鼠标悬停时暂停滚动
autoScrollBooleantrue是否自动开始滚动
forceScrollingBooleanfalse是否强制滚动(即使内容未超出容器)
dataT[]必填要显示的数据数组(支持泛型T)
containerHeightString|Number'100%'容器高度,支持像素值或CSS单位
containerWidthString|Number'100%'容器宽度,支持像素值或CSS单位
customClassString-自定义容器CSS类名
styleObject-自定义容器style
itemSizeNumber-固定项目尺寸(像素),用于虚拟滚动的固定高度模式
minItemSizeNumber-最小项目尺寸(像素),用于虚拟滚动的动态高度模式
virtualScrollBufferNumber5虚拟滚动缓冲区大小,值越大滚动越平滑但渲染项目更多
itemKeyString|Function-项目键名或函数 (item: T, index: number) => string|number
onItemClick(item: T, index: number) => void-当列表项被点击时触发,参数为点击的数据项和索引
children(item: T, index: number) => ReactNode | ReactElement-自定义列表项的渲染方式,支持泛型完整类型推断
emptyRenderReactNode"无数据"当数据为空时显示的内容

方法

通过组件 ref 可以访问以下方法:

方法名参数返回值说明
start-void开始滚动
stop-void停止滚动
pause-void暂停滚动
resume-void恢复滚动
reset-void重置滚动状态
forceScroll-void强制开始滚动
updateSize-void更新容器和列表容器尺寸计算
setObserver(container: HTMLElement, realList: HTMLElement)void更新容器和列表内容尺寸计算
clearObserver-void清除观察者
resetObserver-void重置观察者以观察最新的 DOM
updateItemSizeList(index: number, size: number, type?: string)void更新指定索引项目的尺寸缓存
predictItemSize(index: number, type?: string)number预测指定索引项目的尺寸

虚拟滚动功能

SeamlessScroll 组件内置了高性能的虚拟滚动功能,适用于大数据量渲染场景。

虚拟滚动自动启用条件

  • 当数据项数量较多时,组件会自动启用虚拟滚动
  • 当内容尺寸明显大于容器尺寸时,也会自动启用

虚拟滚动模式

  1. 固定高度模式

    • 适用于所有项目高度相同的场景
    • 配置:设置 itemSize 属性为固定像素值
  2. 动态高度模式

    • 适用于项目高度不同的场景
    • 配置:设置 minItemSize 属性作为最小高度基准
    • 组件会自动测量和记忆每个项目的实际高度

相关类型

typescript
export type VirtualScrollItem<T = any> = T & {
  _originalIndex: number; // 原始数据中的索引位置
};

useSeamlessScroll Hook

useSeamlessScroll Hook 现在支持泛型类型 <T>,以便更好地与 TypeScript 集成:

typescript
function useSeamlessScroll<T>(props: HooksProps): {
  containerRef: React.RefObject<HTMLDivElement>;
  contentRef: React.RefObject<HTMLDivElement>;
  realListRef: React.RefObject<HTMLDivElement>;
  state: Readonly<ScrollState>;
  methods: ScrollMethods;
  getVirtualItems: (data: T[]) => VirtualScrollItem<T>[];
  styles: () => ReactSeamlessScrollStyles;
};

相关状态字段

状态字段类型描述
isVirtualizedboolean是否启用了虚拟滚动
startIndexnumber当前可见区域的起始索引
endIndexnumber当前可见区域的结束索引
itemSizeListnumber[]已测量的每个项目尺寸列表
averageSizenumber所有已测量项目的平均尺寸
totalMeasuredItemsnumber已测量的项目数量
typeSizesobject按类型统计的尺寸信息

用法示例

tsx
import { useRef, useState } from "react";
import { useSeamlessScroll } from "@seamless-scroll/react";

interface Product {
  id: number;
  name: string;
  price: number;
}

function VirtualList() {
  const [products, setProducts] = useState<Product[]>([
    { id: 1, name: "商品1", price: 100 },
    { id: 2, name: "商品2", price: 200 },
    // ...更多数据
  ]);

  const { containerRef, realListRef, contentRef, state, methods, getVirtualItems } =
    useSeamlessScroll<Product>({
      dataTotal: products.length,
      speed: 50,
      direction: "vertical",
      minItemSize: 60,
    });

  // getVirtualItems 会返回 VirtualScrollItem<Product>[] 类型
  const virtualProducts = getVirtualItems(products);

  return (
    <div ref={containerRef} className="container">
      <div ref={contentRef} className="content">
        <div ref={realListRef} className="list">
          {virtualProducts.map((item) => (
            <div key={item.id} className="product-item">
              {item.name} - ¥{item.price}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

基于 MIT 许可发布