You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React Table的ColumnDef中更新主组件useState打开删除对话框

React Table ColumnDef触发主组件删除对话框的解决方案

问题背景

刚接触TypeScript和React,使用react-table开发项目时,无法从ColumnDef中更新主组件的useState状态,需要通过ColumnDef内的删除按钮打开主组件中的删除对话框。

解决方案

核心思路是让ColumnDef能够接收主组件的回调函数——全局定义的columns无法直接访问主组件的状态和方法,我们可以将columns改为一个可接收参数的函数,或者直接在主组件内部定义columns。

步骤1:重构Columns为可接收回调的函数

将原来的全局columns定义改为一个函数,接收打开删除对话框的回调作为参数:

// 替换原来的export const columns
const createColumns = (onDeleteClick: (id: string) => void): 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={() => {
                // 调用传入的回调,传递当前组件ID
                onDeleteClick(component._id);
              }}
            >
              Delete
            </DropdownMenuItem>
            <DropdownMenuSeparator />
            <DropdownMenuItem
              onClick={() => navigate("/documents/" + component._id)}
            >
              Show Documents
            </DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      );
    },
  },
  // 其他列定义...
];

步骤2:在主组件中添加删除ID状态

新增状态保存当前要删除的组件ID,用于传递给对话框:

export function ComponentsDataTable() {
  const [deleteComponentOpen, setDeleteComponentOpen] = React.useState(false);
  // 新增状态保存要删除的ID
  const [deleteComponentId, setDeleteComponentId] = React.useState<string>("");
  
  // ...其他原有代码

  // 定义打开对话框的回调
  const handleDeleteClick = (id: string) => {
    setDeleteComponentId(id);
    setDeleteComponentOpen(true);
  };

步骤3:创建table时传入自定义columns

调用createColumns并传入我们的回调函数:

const table = useReactTable({
    data,
    // 传入生成的columns,带上回调
    columns: createColumns(handleDeleteClick),
    onSortingChange: setSorting,
    onColumnFiltersChange: setColumnFilters,
    getCoreRowModel: getCoreRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getSortedRowModel: getSortedRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    onColumnVisibilityChange: setColumnVisibility,
    onRowSelectionChange: setRowSelection,
    state: {
      sorting,
      columnFilters,
      columnVisibility,
      rowSelection,
    },
  });

步骤4:更新对话框的props传递

将保存的删除ID传递给对话框:

return (
    // ...其他原有代码
    <DeleteAlertDialog
      open={deleteComponentOpen}
      id={deleteComponentId}
      handleOpen={(value) => setDeleteComponentOpen(value)}
    />
  );
}

原理说明

通过将columns封装为函数,我们可以把主组件的状态更新逻辑(打开对话框、设置删除ID)作为参数传递进去,让ColumnDef里的按钮能够触发主组件的状态变化。这种方式既保留了columns的复用性,又解决了跨组件状态更新的问题。

内容的提问来源于stack exchange,提问作者lexer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 15:40:05