🎍
react-tableでソート機能を実装(TypeScript)
記事を書いているときのバージョン7.7.0
(@types/react-table
は7.7.5
)にて、
ソート機能がなかなか実装できなかったので、できるまでを書いていきます。
普通に実装した際の問題点
まず、公式のガイド通りに実装してみると、
ソート機能を有効化させるプロパティは存在しないエラーが出てしまいます。
Property 'getSortByToggleProps' does not exist on type 'HeaderGroup<CategoryTable | TagTable>'.ts(2339)
解決策
この方の解決策をそのまま行うことによって解決いたしました。
プロジェクト/src
の直下にtypes/react-table-config.d.ts
ファイルを作成し、
そのファイルに下記を記載します。
プロジェクト/src/types/react-table-config.d.ts
import {
UseColumnOrderInstanceProps,
UseColumnOrderState,
UseExpandedHooks,
UseExpandedInstanceProps,
UseExpandedOptions,
UseExpandedRowProps,
UseExpandedState,
UseFiltersColumnOptions,
UseFiltersColumnProps,
UseFiltersInstanceProps,
UseFiltersOptions,
UseFiltersState,
UseGlobalFiltersColumnOptions,
UseGlobalFiltersInstanceProps,
UseGlobalFiltersOptions,
UseGlobalFiltersState,
UseGroupByCellProps,
UseGroupByColumnOptions,
UseGroupByColumnProps,
UseGroupByHooks,
UseGroupByInstanceProps,
UseGroupByOptions,
UseGroupByRowProps,
UseGroupByState,
UsePaginationInstanceProps,
UsePaginationOptions,
UsePaginationState,
UseResizeColumnsColumnOptions,
UseResizeColumnsColumnProps,
UseResizeColumnsOptions,
UseResizeColumnsState,
UseRowSelectHooks,
UseRowSelectInstanceProps,
UseRowSelectOptions,
UseRowSelectRowProps,
UseRowSelectState,
UseRowStateCellProps,
UseRowStateInstanceProps,
UseRowStateOptions,
UseRowStateRowProps,
UseRowStateState,
UseSortByColumnOptions,
UseSortByColumnProps,
UseSortByHooks,
UseSortByInstanceProps,
UseSortByOptions,
UseSortByState,
} from 'react-table'
declare module 'react-table' {
// take this file as-is, or comment out the sections that don't apply to your plugin configuration
export interface TableOptions<
D extends Record<string, unknown>
> extends UseExpandedOptions<D>,
UseFiltersOptions<D>,
UseGlobalFiltersOptions<D>,
UseGroupByOptions<D>,
UsePaginationOptions<D>,
UseResizeColumnsOptions<D>,
UseRowSelectOptions<D>,
UseRowStateOptions<D>,
UseSortByOptions<D>,
// note that having Record here allows you to add anything to the options, this matches the spirit of the
// underlying js library, but might be cleaner if it's replaced by a more specific type that matches your
// feature set, this is a safe default.
Record<string, any> {}
export interface Hooks<
D extends Record<string, unknown> = Record<string, unknown>
> extends UseExpandedHooks<D>,
UseGroupByHooks<D>,
UseRowSelectHooks<D>,
UseSortByHooks<D> {}
export interface TableInstance<
D extends Record<string, unknown> = Record<string, unknown>
> extends UseColumnOrderInstanceProps<D>,
UseExpandedInstanceProps<D>,
UseFiltersInstanceProps<D>,
UseGlobalFiltersInstanceProps<D>,
UseGroupByInstanceProps<D>,
UsePaginationInstanceProps<D>,
UseRowSelectInstanceProps<D>,
UseRowStateInstanceProps<D>,
UseSortByInstanceProps<D> {}
export interface TableState<
D extends Record<string, unknown> = Record<string, unknown>
> extends UseColumnOrderState<D>,
UseExpandedState<D>,
UseFiltersState<D>,
UseGlobalFiltersState<D>,
UseGroupByState<D>,
UsePaginationState<D>,
UseResizeColumnsState<D>,
UseRowSelectState<D>,
UseRowStateState<D>,
UseSortByState<D> {}
export interface ColumnInterface<
D extends Record<string, unknown> = Record<string, unknown>
> extends UseFiltersColumnOptions<D>,
UseGlobalFiltersColumnOptions<D>,
UseGroupByColumnOptions<D>,
UseResizeColumnsColumnOptions<D>,
UseSortByColumnOptions<D> {}
export interface ColumnInstance<
D extends Record<string, unknown> = Record<string, unknown>
> extends UseFiltersColumnProps<D>,
UseGroupByColumnProps<D>,
UseResizeColumnsColumnProps<D>,
UseSortByColumnProps<D> {}
export interface Cell<
D extends Record<string, unknown> = Record<string, unknown>,
V = any
> extends UseGroupByCellProps<D>,
UseRowStateCellProps<D> {}
export interface Row<
D extends Record<string, unknown> = Record<string, unknown>
> extends UseExpandedRowProps<D>,
UseGroupByRowProps<D>,
UseRowSelectRowProps<D>,
UseRowStateRowProps<D> {}
}
これでuseSortBy
を使用した際に、足りてなかった定義を使用してもエラーが吐かれるということはなくなります。
このライブラリはHooks化してあるので、useSortBy
を使用するときはuseMemo()
を使い、ヘッダーやデータを渡すようにしたら完璧です。
useMemo()を使って値を渡す
table.tsx
...
type TTable = {
id: number
name: string
}
const columns: Column<TTable>[] = useMemo(
() => [
{
Header: 'ID',
accessor: 'id',
sortType: 'basic',
},
{
Header: '名前',
accessor: 'name',
},
],
[]
)
const data: TTable[] = useMemo(
() => [
{
id: 1,
name: 'AAA',
},
{
id: 1,
name: 'BBB',
},
],
[]
)
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } =
useTable<TTable>({ columns, data }, useSortBy)
...
これで実際にreact-table
のソート機能を使うことができます。
この解決策見つけれなかったら、簡易的に自作するか他のライブラリ使うところでした🥵
Discussion