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, basketball
と soccer, 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
に配列要素を展開して表示する処理を記述する必要がある。