🐙

【React】React Tableを使用してテーブルソート

2022/03/21に公開

概要

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