React Virtuosoの4つのコンポーネント紹介

はじめに


こんにちは、ナオキです!
前回Reactのライブラリである「React Virtuoso」について紹介をしました。

今回はその「React Virtuoso」のコンポーネントを使用し多様なリストの作成方法を紹介します。前回の記事でReact Virtuosoについての説明をしているのでこの記事では細かな説明は省かせてもらいます。
ぜひ参考にしてもらえると嬉しいです!

概要

「React Virtuoso」はReactライブラリで、沢山のDOM要素をもつリストやテーブルを仮想化して表示するためのライブラリです。画面の表示領域に入っている要素のみをレンダリングさせるのでパフォーマンス向上に適しています!
React Virtuosoには4つのコンポーネント(VirtuosoGrouped VirtuosoTable VirtuosoVirtuoso Grid)があります。
それぞれを使用したリスト作成の紹介をします。

対象読者

  • React初学者の方
  • React Virtuosoを使用してパフォーマンス改善をしようとしてる方

開発環境

  • react: “18.2.0”
  • react-virtuoso: “^4.7.4”
  • tailwindcss: “^3.3.3”
  • typescript: “^5.3.3”

今回はTailwindcssを使用しています!

Virtuosoコンポーネント

React Virtuosoライブラリのコンポーネントで一番基本的なコンポーネントです。

Virtuosoを使用したサンプルリスト

コード

import { Virtuoso } from "react-virtuoso"

export default function App() {
  return (
    <Virtuoso
      style={{ height: 500, width: 400 }}  /* リストの表示領域を指定 */
      totalCount={1000}  /* リスト要素の総数を指定 */
      itemContent={(index) => (
        <div className="flex flex-col items-center justify-center border p-3">  /* 要素のスタイルを指定 */
          <p>user {index}</p>
        </div>
      )}
    />
  )
}

表示させたい領域をwidthheightで指定しています。
totalCountでは表示させたい要素の数を指定します。

Grouped Virtuosoコンポーネント

グループ形式のデータを表示させるためのコンポーネントです。

Grouped Virtuosoを使用したサンプルリスト

コード

import React, { useMemo } from "react"
import { GroupedVirtuoso } from "react-virtuoso"

export default function App() {
  const groupCounts = useMemo(() => {
    return Array(1000).fill(10)  /* グループの総数と1つのグループに含まれる要素を指定 */
  }, [])

  return (
    <GroupedVirtuoso
      style={{  /* リストの表示領域を指定 */
        height: 600,
        width: 400,
      }}
      groupCounts={groupCounts}
      groupContent={(index: number) => {  /* 各グループのスタイルやコンテンツを指定 */
        return <div className="bg-gray-500 p-3 text-white">Group {index}</div>
      }}
      itemContent={(index: number, groupIndex: number) => (  /* 各要素のスタイルやコンテンツを指定 */
        <div className="border p-3">
          {index} (group {groupIndex})
        </div>
      )}
    />
  )
}

groupCountsでグループの総数と1つのグループに含まれる要素数を指定しています。
Array(1000)でグループの総数を1000個に指定し、fill(10)で1つのグループに含まれる要素を10個に指定しています。
リストのヘッダー部分のスタイルをgroupContentで指定しています。

Table Virtuosoコンポーネント

テーブル形式のデータを表示させるためのコンポーネントです。

Table Virtuosoを使用したサンプルリスト

コード

import React, { useMemo } from "react"
import { TableVirtuoso } from "react-virtuoso"

type User = {  /* User型を定義 */
  name: string
  age: number
  description: string
  gender: string
}

export default function App() {
  const users: User[] = useMemo(() => {
    return Array.from({ length: 1000 }, (_, index) => ({ /* テーブルに表示する1000個のユーザーデータを作成 */
      name: `User ${index}`,
      age: 20,
      description: `Description for user ${index}`,
      gender: index % 2 === 0 ? "男性" : "女性",  /* indexが偶数なら男性、奇数なら女性と表示させる */
    }))
  }, [])

  return (
    <TableVirtuoso
      style={{ height: 590, width: 600 }}  /* リストの表示領域を指定 */
      data={users}  /* テーブルに表示されるデータを指定 */
      components={{
        Table: ({ style, ...props }) => (
          <table {...props} style={{ ...style, width: "100%" }} />  /* テーブル全体のスタイルを指定 */
        ),
      }}
      fixedHeaderContent={() => (  /* 固定されたリストのヘッダーのスタイルを指定 */
        <tr>
          <th className="border bg-gray-500 p-3 text-white">Name</th>
          <th className="border bg-gray-500 p-3 text-white">Gender</th>
          <th className="border bg-gray-500 p-3 text-white">Age</th>
          <th className="border bg-gray-500 p-3 text-white">Description</th>
        </tr>
      )}
      itemContent={(_, user) => (  /* リスト要素のスタイルを指定 */
        <>
          <td className="border p-3 text-center">{user.name}</td>
          <td className="border p-3 text-center">{user.gender}</td>
          <td className="border p-3 text-center">{user.age}</td>
          <td className="border p-3 text-center">{user.description}</td>
        </>
      )}
    />
  )
}

dataでテーブルに表示させるデータを取得しています。
リストの上部に固定されるヘッダーのスタイルをfixedHeaderContentで指定し、リスト要素のスタイルをitemContentで指定します!

Virtuoso Gridコンポーネント

グリッド形式のデータを表示するためのコンポーネントです。

Virtuoso Gridを使用したサンプルリスト

コード

import React from "react"
import { VirtuosoGrid } from "react-virtuoso"

export default function App() {
  return (
    <>
      <VirtuosoGrid
        style={{ height: 500, width: 600 }}  /* リストの表示領域を指定 */
        listClassName="grid grid-cols-3 gap-3 border"  /* リストの形式をグリットに指定 */
        itemClassName="p-3 border text-center"  /* リスト要素のスタイルを指定 */
        totalCount={1000}  /* リスト要素の総数を指定 */
        itemContent={(index: number) => (
          <div>
            <p>user {index}</p>
          </div>
        )}
      />
    </>
  )
}

listClassNameでリストの形式をグリッドに指定しています。
リスト要素のスタイルはitemClassNameで指定しています!

さいごに

今回はReact VirtuosoのコンポーネントであるVirtuoso, Grouped Virtuoso, Table Virtuoso, Virtuoso Gridそれぞれのリストの紹介をしました。
コードを見てもらえると分かる通りとてもシンプルで簡単に実装ができます!
ぜひリスト作成をするときに使ってみてください!