提问人:lexer 提问时间:10/30/2023 更新时间:11/1/2023 访问量:41
从 React Table ColumnDef 在功能组件中设置状态
Set State in Functional Component from React Table ColumnDef
问:
嘿,我刚刚拿到打字稿和 react,并开始制作一个使用 react-table 的项目。
现在我面临的问题是我不知道如何从 ColumnDef 更新我的主要功能组件的状态 (useState)。
所以基本上我想使用 react-table 的 ColumnDef 中定义的按钮打开一个删除对话框。
列定义:
export const columns: ColumnDef<Component>[] = [
{
id: "actions",
enableHiding: false,
cell: ({ row }) => {
const component = row.original;
const navigate = useNavigate();
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="h-8 w-8 p-0">
<span className="sr-only">Open menu</span>
<MoreHorizontal className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuItem
onClick={() => {
navigator.clipboard.writeText(component.articleNumber);
toast({
title: "✅ Copied Article Number",
});
}}
>
Copy Article Number
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
// **OPEN THE DELETE DIALOG**
}}
>
Delete
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
onClick={() => navigate("/documents/" + component._id)}
>
Show Documents
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
},
},
];
对话:
interface DeleteAlertDialogProps {
open: boolean;
id: string;
handleOpen: (value: boolean) => void;
}
function DeleteAlertDialog({ open, id, handleOpen }: DeleteAlertDialogProps) {
return (
<AlertDialog open={open}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
<AlertDialogDescription>{id}</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel onClick={() => handleOpen(false)}>
Cancel
</AlertDialogCancel>
<AlertDialogAction>Continue</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
}
主要成分:
export function ComponentsDataTable() {
const [deleteComponentOpen, setDeleteComponentOpen] = React.useState(false);
const accessToken = "FAKE";
const url = "http://localhost:3000/api/v1/components";
const fetcher = (url: string) => fetchData(url, accessToken);
const { data, mutate } = useSWR(url, fetcher, {
suspense: true,
});
function handleMutate() {
mutate();
}
const [sorting, setSorting] = React.useState<SortingState>([]);
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
);
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({});
const [rowSelection, setRowSelection] = React.useState({});
const table = useReactTable({
data,
columns,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
onRowSelectionChange: setRowSelection,
state: {
sorting,
columnFilters,
columnVisibility,
rowSelection,
},
});
**I SOMEHOW NEED TO PASS THIS FUNCTION TO THE COLUMNDEF ????**
function handleDeleteComponentOpen(value: boolean) {
setDeleteComponentOpen(value);
}
return (
<div className="w-full">
<div className="flex items-center space-x-4 py-4">
<Input
placeholder="Filter Tagname..."
value={(table.getColumn("tagname")?.getFilterValue() as string) ?? ""}
onChange={(event) =>
table.getColumn("tagname")?.setFilterValue(event.target.value)
}
className="max-w-sm"
/>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" className="ml-auto">
Columns <ChevronDown className="ml-2 h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{table
.getAllColumns()
.filter((column) => column.getCanHide())
.map((column) => {
return (
<DropdownMenuCheckboxItem
key={column.id}
className="capitalize"
checked={column.getIsVisible()}
onCheckedChange={(value) =>
column.toggleVisibility(!!value)
}
>
{column.id}
</DropdownMenuCheckboxItem>
);
})}
</DropdownMenuContent>
</DropdownMenu>
<CreateDialog mutateDataParent={handleMutate} />
</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 className="flex items-center justify-end space-x-2 py-4">
<div className="flex-1 text-sm text-muted-foreground">
{table.getFilteredSelectedRowModel().rows.length} of{" "}
{table.getFilteredRowModel().rows.length} row(s) selected.
</div>
<div className="space-x-2">
<Button
variant="outline"
size="sm"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
>
Previous
</Button>
<Button
variant="outline"
size="sm"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
>
Next
</Button>
</div>
</div>
<DeleteAlertDialog
open={deleteComponentOpen}
id={"test"}
handleOpen={handleDeleteComponentOpen}
/>
</div>
);
}
我找不到任何关于这方面的好信息。 如果有人可以帮助或提供链接,那就太好了。
答:
0赞
lexer
10/30/2023
#1
以防万一有人遇到同样的问题。只需使用一个函数并返回列定义。然后传递一个函数来处理东西。
interface ColumnDefinitionHandlerProps {
handleDeleteComponent: (open: boolean, id: string) => void;
}
export function ColumnDefinitionHandler({
handleDeleteComponent,
}: ColumnDefinitionHandlerProps): ColumnDef<Component>[] {
const columns: ColumnDef<Component>[] = [{/*Definitions*/}]
return columns
}
// Blow Code is inside Main Component
const columns = ColumnDefinitionHandler({ handleDeleteComponent });
const table = useReactTable({
data,
columns: columns,
//...
})
评论