如何在Shadcn Data Table中设置默认选中行?
实现编辑集合时默认选中已有产品的方案
要让表格默认选中集合中已有的产品,你需要给TanStack Table配置行选择功能,并利用传入的checkedData初始化选中状态,具体步骤如下:
1. 启用行选择并配置唯一行标识
首先在useReactTable的配置中开启行选择,同时指定getRowId来确保每行有唯一标识(比如产品ID),这样才能精准匹配已选中的产品:
const table = useReactTable({ data, columns, getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), // 启用行选择功能 enableRowSelection: true, // 定义行的唯一ID,这里假设产品数据有id字段,根据实际字段调整 getRowId: (row) => row.id, });
2. 同步已有产品的选中状态
用useEffect监听checkedData的变化,将其中的产品转换成TanStack Table需要的选中状态格式(键为行ID、值为布尔值的对象),然后设置表格选中状态:
useEffect(() => { if (!checkedData.length) { // 无已选数据时清空选中状态 table.setRowSelection({}); return; } // 把已有的产品映射成选中状态对象 const selectionMap = checkedData.reduce((acc, item) => { acc[item.id] = true; return acc; }, {} as Record<string, boolean>); table.setRowSelection(selectionMap); }, [checkedData, table]);
完整修改后的组件代码
整合上述配置后的完整组件代码如下:
"use client"; import { ColumnDef, flexRender, getCoreRowModel, getFilteredRowModel, useReactTable, } from "@tanstack/react-table"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import React, { useEffect } from "react"; interface DataTableProps<TData, TValue> { columns: ColumnDef<TData, TValue>[]; data: TData[]; checkedData: TData[]; } export function DataTable<TData, TValue>({ columns, data, checkedData, }: DataTableProps<TData, TValue>) { const table = useReactTable({ data, columns, getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), enableRowSelection: true, // 注意:如果你的产品唯一标识不是id,替换成对应字段(如productId) getRowId: (row: TData) => (row as any).id, }); useEffect(() => { if (!checkedData.length) { table.setRowSelection({}); return; } const selectionMap = checkedData.reduce((map, item) => { map[(item as any).id] = true; return map; }, {} as Record<string, boolean>); table.setRowSelection(selectionMap); }, [checkedData, table]); return ( <div> <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> </div> ); }
关键注意事项
- 确保
getRowId使用的字段是产品数据的唯一标识,否则会出现选中匹配错误。 - 如果你的
TData类型明确包含唯一标识字段,可以把(row as any).id改成类型安全的写法,比如给DataTableProps加约束TData extends { id: string }。 - 当
checkedData变化时(比如编辑集合时从接口获取到已有产品),useEffect会自动同步表格的选中状态。
内容的提问来源于stack exchange,提问作者Apollo Vostok
相关产品推荐
相关产品推荐

