Skip to content

React Table v8における配列要素のセル表示とフィルタリングの実装ガイド

Published:

Table of contents

Open Table of contents

はじめに

tanstack/react-table v8 で配列要素のフィルタリング実装でハマったので、実装方法について整理する。

配列要素を 1 つのセルに表示する

配列要素を 1 つのセルに表示するには、cell に配列要素を展開して表示する。

const data: datatype = [
  {
    id: 1,
    name: "John",
    hobbies: ["soccer", "basketball"],
  },
  {
    id: 2,
    name: "Jane",
    hobbies: ["soccer", "baseball"],
  },
];

const columns: ColumnDef<datatype>[] = [
  {
    header: "Name",
    accessor: "name",
  },
  {
    header: "Hobbies",
    accessor: "hobbies",
    cell: ({ row }) => {
      return row
        .map(hobby => {
          hobby;
        })
        .join(", ");
    },
  },
];

accessor に配列要素のプロパティを指定すると、配列要素のプロパティが表示される。 したがって、hobbies には、soccer, basketballsoccer, baseball が表示される。

配列要素をフィルタリングする

react-table 側のフィルター機能を実装する。必要な箇所だけ抜粋する。

  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    onColumnFiltersChange: setColumnFilters,
    getFilteredRowModel: getFilteredRowModel(),
    state: {
      columnFilters,
    },
  });

  return (
    <div>
      <div className="flex items-center py-4">
        <Input
          placeholder="Search"
          value={(table.getColumn("hobbies")?.getFilterValue() as string) ?? ""}
          onChange={(e) =>
            table.getColumn("hobbies")?.setFilterValue(e.target.value)
          }
          className="max-w-sm"
        />
      </div>
    ...

上記のようにフィルター機能を実装すると、hobbies のフィルターが実装できるはずだったが、実際にはフィルターが効かなかった。 name に対してはフィルターが効いたので、フィルター機能自体は正しく実装できていると思われる。

フィルター機能が効かない原因

フィルター機能が効かない原因は、cell に配列要素を展開して表示していることにある。 正しくは、 accessorFn に配列要素を展開して表示する処理を記述する必要がある。

const columns: ColumnDef<datatype>[] = [
  {
    header: "Name",
    accessor: "name",
  },
  {
    header: "Hobbies",
    accessorFn: ({ row }) => {
      return row
        .map(hobby => {
          hobby;
        })
        .join(" ");
    },
  },
];

上記のように実装すると、hobbies のフィルターが効くようになった。カンマ区切りでフィルターも同様に実装できる。

まとめ

react-table で配列要素を 1 つのセルに表示するには、cell に配列要素を展開して表示する。 しかし、cell に配列要素を展開して表示すると、フィルター機能が効かなくなる。 フィルター機能を実装する場合は、accessorFn に配列要素を展開して表示する処理を記述する必要がある。

最近話題の本

ソフトウェアアーキテクチャの基礎 ―エンジニアリングに基づく体系的アプローチ