はじめに
こんにちは、ナオキです!
前回Reactのライブラリである「React Virtuoso」について紹介をしました。
今回はその「React Virtuoso」のコンポーネントを使用し多様なリストの作成方法を紹介します。前回の記事でReact Virtuosoについての説明をしているのでこの記事では細かな説明は省かせてもらいます。
ぜひ参考にしてもらえると嬉しいです!
概要
「React Virtuoso」はReactライブラリで、沢山のDOM要素をもつリストやテーブルを仮想化して表示するためのライブラリです。画面の表示領域に入っている要素のみをレンダリングさせるのでパフォーマンス向上に適しています!
React Virtuosoには4つのコンポーネント(Virtuoso、Grouped Virtuoso、Table Virtuoso、Virtuoso 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ライブラリのコンポーネントで一番基本的なコンポーネントです。
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>
)}
/>
)
}
表示させたい領域をwidth
とheight
で指定しています。totalCount
では表示させたい要素の数を指定します。
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コンポーネント
テーブル形式のデータを表示させるためのコンポーネントです。
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コンポーネント
グリッド形式のデータを表示するためのコンポーネントです。
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それぞれのリストの紹介をしました。
コードを見てもらえると分かる通りとてもシンプルで簡単に実装ができます!
ぜひリスト作成をするときに使ってみてください!