TRPC 在 Tanstack 表列定义中的 useMutation

问题描述 投票:0回答:1

遵循 Shadcn 数据表 文档中的示例。当我在

columns.tsx
中调用 trpc 的 useMutation 时(参见下面 DropdownMenuItem 中的 onClick 事件),我得到了错误:

“无效的钩子调用。钩子只能在函数组件的主体内部调用”。

我该如何处理这个行删除突变?

app
└── payments
    ├── columns.tsx
    ├── data-table.tsx
    └── page.tsx

页面.tsx

import { Payment, columns } from "./columns"
import { DataTable } from "./data-table"

async function getData(): Promise<Payment[]> {
  // Fetch data from your API here.
  return [
    {
      id: "728ed52f",
      amount: 100,
      status: "pending",
      email: "[email protected]",
    },
    // ...
  ]
}

export default async function DemoPage() {
  const data = await getData()

  return (
    <div>
      <DataTable columns={columns} data={data} />
    </div>
  )
}

列.tsx

"use client"

import { ColumnDef } from "@tanstack/react-table"
import { MoreHorizontal } from "lucide-react"

import { Button } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"

export const columns: ColumnDef<Payment>[] = [
  // ...
  {
    id: "actions",
    cell: ({ row }) => {
      const payment = row.original

      return (
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button variant="ghost" className="h-8 w-8 p-0">
              <span className="sr-only">Open menu</span>
            </Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end">
            <DropdownMenuLabel>Actions</DropdownMenuLabel>
            <DropdownMenuItem
              onClick={() => {
                 const mutation = api.transaction.delete.useMutation();
                 mutation.mutate({ id });
              }} 
            >
              Delete
            </DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      )
    },
  },
  // ...
]

next.js trpc
1个回答
0
投票

您想要将

columns
ColumnDef<T>
数组更改为返回
ColumnDef<T>
数组的函数。然后,您可以将突变传递给
columns
函数,如下所示:

列.tsx

"use client";

import { ColumnDef } from "@tanstack/react-table";

import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";

export type Payment = {
  id: string;
  amount: number;
  status: "pending" | "processing" | "success" | "failed";
  email: string;
};

export function columns(
  mutateAsync: (id: string) => Promise<void>,
): ColumnDef<Payment>[] {
  return [
    // ...
    {
      id: "actions",
      cell: ({ row }) => {
        const payment = row.original;

        return (
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button variant="ghost" className="h-8 w-8 p-0">
                <span className="sr-only">Open menu</span>
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              <DropdownMenuLabel>Actions</DropdownMenuLabel>
              <DropdownMenuItem onClick={() => mutateAsync(payment.id)}>
                Delete
              </DropdownMenuItem>
            </DropdownMenuContent>
          </DropdownMenu>
        );
      },
    },
    // ...
  ];
}

演示数据表.tsx

"use client";
import { columns } from "./columns";
import { DataTable } from "./data-table";
import { api } from "@/trpc/client";

export function DemoDataTable({ data }: { data: Payment[] }) {
  const { mutateAsync } = api.transaction.delete.useMutation();

  return <DataTable columns={columns(mutateAsync)} data={data} />;
}

页面.tsx

import { Payment, columns } from "./columns";
import { DataTable } from "./data-table";
import { DemoDataTable } from "./demo-data-table";

async function getData(): Promise<Payment[]> {
  // Fetch data from your API here.
  return [
    {
      id: "728ed52f",
      amount: 100,
      status: "pending",
      email: "[email protected]",
    },
    // ...
  ];
}

export default async function DemoPage() {
  const data = await getData();

  return (
    <div>
      <DemoDataTable data={data} />
    </div>
  );
}

但这确实需要您创建一个中间数据表客户端组件,您可以在其中从 trpc 获取突变并将它们传递给

columns
函数。

© www.soinside.com 2019 - 2024. All rights reserved.