TRPC's useMutation inside Tanstack table column definition

238 views Asked by At

Following the example in Shadcn datatable docs. When I call trpc's useMutation in columns.tsx (see onClick event in DropdownMenuItem below) I got the error:

"Invalid hook call. Hooks can only be called inside of the body of a function component".

How can I handle this row deletion mutation?

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

page.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>
  )
}

columns.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>
      )
    },
  },
  // ...
]

0

There are 0 answers