はじめに
MUIでソート可能なテーブルを作りたかったのですが、MUIのサンプルはCheckBox、FormControlLabelなどシンプルなものを作るときには不要な機能もついていて、少し分かりにくかったです。
なので、不要な機能を削除したシンプルなソート可能なテーブルをメモ代わりに残しておきます。
作成したもの
商品の名前と価格を表示するテーブルです。
価格によってソート可能です。
コード
import { useState, VFC } from "react";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import TableSortLabel from "@mui/material/TableSortLabel";
interface Data {
id: number;
name: string;
value: number;
}
function createData(id: number, name: string, value: number): Data {
return {
id,
name,
value
};
}
const rows = [
createData(1, "Frozen yoghurt", 305),
createData(2, "Ice cream sandwich", 302),
createData(3, "Eclair", 303),
createData(4, "Cupcake", 303),
createData(5, "Marshmallow", 306)
];
function descendingComparator<T>(a: T, b: T, orderBy: keyof T) {
if (b[orderBy] < a[orderBy]) {
return -1;
}
if (b[orderBy] > a[orderBy]) {
return 1;
}
return 0;
}
type Order = "asc" | "desc";
function getComparator<Key extends keyof any>(
order: Order,
orderBy: Key
): (
a: { [key in Key]: number | string },
b: { [key in Key]: number | string }
) => number {
return order === "desc"
? (a, b) => descendingComparator(a, b, orderBy)
: (a, b) => -descendingComparator(a, b, orderBy);
}
export const SimpleTable: VFC = () => {
const [order, setOrder] = useState<Order>("asc");
const createSortHandler = (property: keyof Data) => (
event: React.MouseEvent<unknown>
) => {
setOrder(order === "asc" ? "desc" : "asc");
};
return (
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell>名前</TableCell>
<TableCell>
<TableSortLabel
active
direction={order}
onClick={createSortHandler("value")}
>
値段
</TableSortLabel>
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.sort(getComparator(order, "value")).map((row, index) => {
return (
<TableRow key={row.id}>
<TableCell>{row.name}</TableCell>
<TableCell>{row.value}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
);
};