🐙
【React】React Tableを使用してテーブルソート
概要
Reactでソート付きのテーブルを実装する場合、やりようはいくつかあると思いますが、ライブラリを使用するのがけっこう手軽かなと思います。今回はReact Tableというライブラリを使って、テーブルソートを実装する方法を紹介します。
対応方法
ソート付きのテーブルの実装について、こちらの例を参照すれば、ざっくりとイメージが付けられるかなと思います。useSortBy
というHooksを使用してソートを設定しており、APIドキュメントに仕様の詳細が記載されています。
個人的にけっこう使用するかなと思われる設定を、下記に記載します。
-
initialState.sortBy
Table
の初期化時(initialState)に、初期のソート状態を設定することが可能です。id
に列定義で設定した値、desc
にbool値を設定します。 -
disableSortBy
列の定義で設定することが可能です。列の設定は基本ソート可能になるので、もしソートさせたくない列があれば当該項目をfalse
にします。 -
sortType
列の定義で設定することが可能です。ソートの方法(文字列か数値かなど)を設定します。設定値の詳細はAPIドキュメントに記載あリます。 -
canSort
設定というわけではないのですが、レンダリング時に当該列がソート可能か判定できます。column.canSort
ような形式でbool値が取得できます。
実装サンプル
以下が実装サンプルです。
インプレッション数とクリック数がソート可能で、初期ソートはクリック数の降順にしています。
import React, { useMemo, useEffect, useState } from "react";
import { useTable, useSortBy } from "react-table";
export default function SampleTableComponent(prop) {
const detailThStyle = {
backgroundColor: "gainsboro",
};
// テーブルの列定義
const columns = useMemo(
() => [
{
Header: "商品",
accessor: "item",
disableSortBy: true,
},
{
Header: "ショップ",
accessor: "shop",
disableSortBy: true,
},
{
Header: "投稿日",
accessor: "postDate",
disableSortBy: true,
},
{
Header: (
<span style={{ color: "deepskyblue" }} role="button">
インプレッション数
</span>
),
accessor: "impCount",
sortType: "number",
},
{
Header: (
<span style={{ color: "deepskyblue" }} role="button">
クリック数
</span>
),
accessor: "clckCount",
sortType: "number",
},
],
[]
);
// クリック数の降順が初期状態
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } =
useTable(
{
data: coordinatePostAnalyticsData,
columns: columns,
initialState: {
sortBy: [{ id: "clckCount", desc: true }],
},
},
useSortBy
);
return (
<>
<table {...getTableProps()} border="1">
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th
{...column.getHeaderProps(column.getSortByToggleProps())}
style={detailThStyle}
>
{column.render("Header")}
{column.canSort &&
(() => {
return (
<div>
{column.isSorted
? column.isSortedDesc
? "🔽"
: "🔼"
: ""}
</div>
);
})()}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{prop.rows.map((row, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell) => {
return (
<td {...cell.getCellProps()}>{cell.render("Cell")}</td>
);
})}
</tr>
);
})}
</tbody>
</table>
</>
);
}
表示イメージは以下の通りです。
Discussion