0

Does anyone know how to write a custom sorting fn using Tanstack's React-table? I've been trying to sort a column based on priority (high, medium, low) but the docs are a little confusing as to how to implement.

So far I've declared the module like the docs say:

declare module "@tanstack/table-core" {
  interface SortingFns {
    myCustomSorting: SortingFn<unknown>;
  }
}

Then I used the sortingFns in my table definition with a simple function just to see if I could get it working:

const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    onSortingChange: setSorting,
    getSortedRowModel: getSortedRowModel(),
    state: {
      sorting,
    },
    sortingFns: {
      myCustomSorting: (rowA: any, rowB: any, columnId: any): number => {
        console.log("hi");
        return 0;
      },
    },
  });

I'm calling the toggleSorting fn on my column per click:

                 <TableHead key={header.id} className="text-center">
                    {header.isPlaceholder ? null : (
                      <div
                        onClick={() => header.column.toggleSorting()}
                      >
                        {flexRender(
                          header.column.columnDef.header,
                          header.getContext()
                        )}
                      </div>
                    )}
                  </TableHead>

And finally, I defined the sortingFn in my column definition:

{
      id: "Priority",
      accessorKey: "priority",
      header: "Priority",
      sortingFn: "myCustomSorting"
    },

I am seeing a console log on click, I guess I'm unsure how to implement the sorting function

Mathew
  • 318
  • 11

1 Answers1

0

Got it!

The following works in terms of sorting based on 'priority'.

You can access the value for a column using rowA.original.[column] and then from there it's easy, just create some logic to turn it into a number for comparison like so:

const prioritySort = (rowA: any, rowB: any, columnId: any): number => {
        const value = (A: string): number => {
          return A === "Low" ? 1 : A === "Medium" ? 2 : 3;
        };

        const Anum = value(rowA.original.priority);
        const Bnum = value(rowB.original.priority);

        if (Anum === Bnum) return 0;

        return Anum < Bnum ? 1 : -1;
      }

And call this function in your table declaration:

const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    onSortingChange: setSorting,
    getSortedRowModel: getSortedRowModel(),
    state: {
      sorting,
    },
    sortingFns: {
      myCustomSorting: prioritySort,
    },
  });

Now running column.toggleSorting() will run the function you declared on that column, but I'd still like to memoize it, not sure how if anyone can explain

Mathew
  • 318
  • 11