Search code examples
reactjsnext.jstanstackshadcnuitanstack-table

Trouble Implementing Column Filtering in TanStack/shadcnUI React Table


I'm currently working on a project using TanStack/shadcnUI React Table for a data grid with filtering capabilities. However, I've encountered an issue where the column filter doesn't seem to function as expected. Despite setting the filter, no results are displayed when they should be. enter image description here

Here's the relevant part of my code setup:

DataTable Component (data-table.tsx):

"use client";

// Define the subscription data type based on the columns created
interface TablaSubscripcionesProps {
  columns: ColumnDef<Views<"user_specific_popular_recurrent_gastos">>[];
  data: Views<"user_specific_popular_recurrent_gastos">[];
}

export function TablaSubscripciones({
  columns,
  data,
}: TablaSubscripcionesProps) {
  const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    onColumnFiltersChange: setColumnFilters,
    getFilteredRowModel: getFilteredRowModel(),
    state: {
      columnFilters,
    },
  });
  const { totalPrice, taxDetails, totalPriceSinImpuestos } =
    useSubscriptionData();
  // Convert taxDetails object to an array for easy mapping
  const taxEntries = Object.entries(taxDetails);
  // Log the current filter state
  console.log("Current filter state:", table.getState().columnFilters);
  return (
    <div className="rounded-md border">
      <Card>
        <CardHeader className=" p-4">
          <h2 className="text-lg font-bold">Subscripciones</h2>
          <p className="text-sm ">
            Administra tus subscripciones y observa el precio total.
          </p>
        </CardHeader>
        <CardContent>
          <div className="flex items-center py-4">
            <Input
              placeholder="Filter services by name"
              value={
                (table.getColumn("serviceName")?.getFilterValue() as string) ??
                ""
              }
              onChange={(event) => {
                console.log("Setting filter value to:", event.target.value); // Log the value being set

                table
                  .getColumn("serviceName")
                  ?.setFilterValue(event.target.value);
              }}
              className="max-w-sm"
            />
          </div>
          <Table>
            <TableHeader>
              {table.getHeaderGroups().map((headerGroup) => (
                <TableRow key={headerGroup.id}>
                  {headerGroup.headers.map((header) => (
                    <TableHead key={header.id}>
                      {header.isPlaceholder
                        ? null
                        : flexRender(
                            header.column.columnDef.header,
                            header.getContext()
                          )}
                    </TableHead>
                  ))}
                </TableRow>
              ))}
            </TableHeader>
            <TableBody>
              {table.getRowModel().rows.length > 0 ? (
                table.getRowModel().rows.map((row) => (
                  <TableRow key={row.id}>
                    {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>
        </CardContent>
        <CardFooter className="flex flex-col items-start p-4 bg-gray-100 dark:bg-gray-800">
        </CardFooter>
      </Card>
    </div>
  );
}

Column Definitions (columns.tsx):

  {
    accessorKey: "serviceName",
    header: () => "Service Name",
    cell: ({ row }) => (
      <div className="font-medium">
        Netlfix{row.original.service_name}
      </div>
    ),
  }

Issue: Even when I hardcode "Netflix" into the row data, filtering for "Netflix" yields no results. Here are the console logs when setting the filter:

Setting filter value to: Netflix
Current filter state: [{id: 'serviceName', value: 'Netflix'}]

The filter state shows that the filter is being set correctly, but the table does not display any filtered results.

Could someone help me identify what I might be doing wrong or missing in my implementation to get the filtering to work to work properly?

I was following this documentation: https://ui.shadcn.com/docs/components/data-table#filtering


Solution

  • I found the problem was that the name of the accessorKey must match exactly with the property name in the data object, like serviceName and type here. This ensures that React Table correctly links each column to its corresponding data field.