はるさめ.dev

tanstack-virtual を試してみる in Next.js

投稿日:Fri Jan 26 2024 13:36:38 GMT+0000 (Coordinated Universal Time)

リポジトリ

harusame0616/try-tanstack-virtual

インストール

Installation | TanStack Virtual

$ >
pnpm install @tanstack/react-virtual

サンプル

とりあえず Fixed Example ページを例に src/app/page.tsx をクライアントコンポーネントにして試してみる。

useVirtualizer の estimateSize に設定した値をもとに getTotalSize()virtualItem.size で要素にサイズを設定して固定サイズの仮想スクロールを行う。
sample のまま useRef() だとエラーが出るので useRef(null) に変更している。


"use client";

import { useVirtualizer } from "@tanstack/react-virtual";
import React, { useRef } from "react";

export default function Home() {
  const parentRef = useRef(null);
  const data = Array.from({ length: 10000 }, (_) => Math.random());

  // The virtualizer
  const rowVirtualizer = useVirtualizer({
    count: data.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 35,
  });

  return (
    <main>
      <>
        {/* The scrollable element for your list */}
        <div
          ref={parentRef}
          style={{
            height: `400px`,
            overflow: "auto", // Make it scroll!
          }}
        >
          {/* The large inner element to hold all of the items */}
          <div
            style={{
              height: `${rowVirtualizer.getTotalSize()}px`,
              width: "100%",
              position: "relative",
            }}
          >
            {/* Only the visible items in the virtualizer, manually positioned to be in view */}
            {rowVirtualizer.getVirtualItems().map((virtualItem) => (
              <div
                key={virtualItem.key}
                style={{
                  position: "absolute",
                  top: 0,
                  left: 0,
                  width: "100%",
                  height: `${virtualItem.size}px`,
                  transform: `translateY(${virtualItem.start}px)`,
                  border: "1px solid white",
                  display: "flex",
                  alignItems: "center",
                }}
              >
                Row {virtualItem.index} {data[virtualItem.index]}
              </div>
            ))}
          </div>
        </div>
      </>
    </main>
  );
}

感想

とりあえずコピペしただけだけど簡単に仮想スクロールの実装が行えることは把握した。
ただ当たり前だけどレンダリングされていない要素を ctrl + f で検索はできないのでそのへんは自前で実装が必要になりそう。
How would one search the virtualized list? #481 | GitHub

サンプルに動的なサイズのテーブルの例やスティッキー、無限スクロールなど一通りありそうなので大規模テーブルを扱う場合は試してみたい。

コメント