TanStackAdvanced
Reusable Components — Refactor
Generic DataTable, useProducts hook generalization ও component API design — বাংলায়।
7টি অংশবাংলা ভাষায়
আমাদের Table যতটা generic করা যাবে ততবেশি reusable। DataTable<T> বানালে ভবিষ্যতে customer/order-এর জন্যও কাজ হয়।
generic data-table.tsxtsx
tsx
"use client";
import { useReactTable, flexRender, getCoreRowModel } from "@tanstack/react-table";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
interface DataTableProps<T> {
data: T[];
columns: ColumnDef<T>[];
emptyMessage?: string;
}
export function DataTable<T>({ data, columns, emptyMessage = "ডেটা নেই" }: DataTableProps<T>) {
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
});
if (data.length === 0) {
return <EmptyState message={emptyMessage} />;
}
return (
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<TableHead key={header.id}>
{header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
</TableHead>
))}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows.map((row) => (
<TableRow key={row.id}>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
);
}কখন generic করবেন
| কখন generic | কখন concrete |
|---|---|
| একাধিক entity-তে একই pattern (Customer, Order) | শুধু Product-ই দরকার |
মন্তব্য: ColumnDef<T>[] design-এ column types match | বৃথা abstraction এড়ান |
| আপনি column factory লিখতে চান | সরল ও স্পষ্ট code |
hook reuse
config-চালিত hooksts
ts
function createListHook<TItem>(
key: string,
fetcher: (params: QueryParams) => Promise<ListResponse<TItem>>,
) {
return (keys: QueryParams) => {
const listKey = [key, "list", keys] as const;
return useQuery({
queryKey: listKey,
queryFn: () => fetcher(keys),
placeholderData: keepPreviousData,
});
};
}
export const useProducts = createListHook(
"products",
listProducts as Fetcher<Product>,
);
export const useOrders = createListHook(
"orders",
listOrders as Fetcher<Order>,
);অতিরিক্ত abstraction সাবধান
Reusable components-এর সুবর্ণ নিয়ম — তিনবার duplicate হওয়ার আগে generalize করবেন না। এখানে Pattern-টা সাধারণ, তাই DataTable ও hook factory justified — কিন্তু সব কোড generic করবেন না।
শেষ প্যারায় নিজে practice করুন — কোড কপি করে নিজের এডিটরে চালিয়ে দেখুন।