😽
【NextJs14】NextJs14 と 便利なライブラリ【#17Shadcn-ui DataTable 】
【#17Shadcn-ui DataTable 】
YouTube: https://youtu.be/Qi2w3ZwCA-s
今回はDataTableを使用して、
フェッチしたデータを表示してみます。
npx shadcn-ui@latest add table
npm install @tanstack/react-table
npm install axios
まずは新しくページを作成します。
フェッチするデータはこちらのusersを使用します。
app/(main)/data/page.tsx
import { User, columns } from "./_components/columns";
import { UsersDataTable } from "./_components/users-data-table";
import axios from "axios";
async function getData(): Promise<User[]> {
try {
const res = await axios.get("https://jsonplaceholder.typicode.com/users");
return res.data;
} catch (error) {
console.log(error);
return [];
}
}
const DataPage = async () => {
const data = await getData();
return (
<div className="container mx-auto py-10">
<UsersDataTable columns={columns} data={data} />
</div>
);
};
export default DataPage;
そしてテーブル用のコンポーネントをdataフォルダに作成します。
app/(main)/data/_components/columns.tsx
"use client";
import { ColumnDef } from "@tanstack/react-table";
export type User = {
id: number;
name: string;
username: string;
email: string;
address?: {
street: string;
suite: string;
city: string;
zipcode: string;
geo: {
lat: string;
lng: string;
};
};
phone?: string;
website?: string;
company?: {
name: string;
catchPhrase: string;
bs: string;
};
};
export const columns: ColumnDef<User>[] = [
{
accessorKey: "id",
header: "ID",
},
{
accessorKey: "email",
header: "Email",
},
{
accessorKey: "username",
header: "Username",
},
{
accessorKey: "name",
header: "Name",
},
];
app/(main)/data/_components/users-data-table.tsx
"use client";
import {
ColumnDef,
flexRender,
getCoreRowModel,
useReactTable,
} from "@tanstack/react-table";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[];
data: TData[];
}
export function UsersDataTable<TData, TValue>({
columns,
data,
}: DataTableProps<TData, TValue>) {
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
});
return (
<div className="rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</TableHead>
);
})}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && "selected"}
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={columns.length} className="h-24 text-center">
No results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
);
}
Discussion