Material UIでソート機能を実装する。
成果物の完成イメージ
App.tsx
import { SampleTable } from "./SampleTable";
export default function App() {
return <SampleTable />;
}
SampleTable.tsx
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 TableLayout {
id: number;
name: string;
score: number;
}
function createData(id: number, name: string, score: number): TableLayout {
return {
id,
name,
score,
};
}
const rows = [
createData(1, "Koji", 75),
createData(2, "Bryant", 48),
createData(3, "k.k.Factory", 89),
createData(4, "Subaru", 78),
createData(5, "Yokosawa", 55)
];
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 SampleTable: VFC = () => {
const [order, setOrder] = useState<Order>("asc");
const handleOrderChange = (property: keyof TableLayout) => (
event: React.MouseEvent<unknown>
) => {
setOrder(order === "asc" ? "desc" : "asc");
};
return (
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell>
<TableSortLabel
active
direction={order}
onClick={handleOrderChange("id")}>ID</TableSortLabel>
</TableCell>
<TableCell>
氏名
</TableCell>
<TableCell>
成績
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.sort(getComparator(order, "id")).map((row, index) => {
return (
<TableRow key={row.id}>
<TableCell>{row.id}</TableCell>
<TableCell>{row.name}</TableCell>
<TableCell>{row.score}</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
);
};