javascriptreactjsfrontendtanstack-table

Selectable row in Tanstack Table in React


I have a table I built with Tanstack table in React. I am trying to do a selectable row functionality but I am currently running into an issue where whenever I click on any row, it always selects the first row and when I click on any row again, it unselects, so it feels all the rows on the table acts as a toggle for the first row. I have tried several solutions like letting each item have a unique ID but it still doesn’t work. I currently handle the select with a checkbox. How can I fix the issue such that whenever I click on a row, it selects that particular, and whenever I click for the second time it unselects (a toggle for each row).

My code:

// columns definition

const columns = [
    {
        id: "select",
        header: ({ table }) => (
            <div className="transform translate-y-[5px]">
                <CheckBoxButton 
                                   checked={table.getIsAllPageRowsSelected()}
                   className="check-minus"
                   name="select"
                   onChange={table.getToggleAllRowsSelectedHandler()}
                />
            </div>
        ),
        cell: ({ row }) => {
            return (
                <div className="transform translate-y-[5px]">
                  <CheckBoxButton
                    checked={row.getIsSelected()}
                    name=”item”
                    onChange {row.getToggleSelectedHandler()}
                    />
                </div>
            );
        },
    },
…
]

const [rowSelection, setRowSelection] = useState({});
const cols = columns;
const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    state: {
          rowSelection,
    },
    onRowSelectionChange: setRowSelection,
});

// my table component
Table
     allowSelection
     page={2}
     pageCount={20}
     table={table}
/>


Solution

  • I think this is related to ID but you already mentioned that you are using a unique ID for each item with Math.random(). I think you can try making your checkbox name unique instead of “item”. Try using name=”item-${row.original.id}” (assuming your unique is id) since you’re using a checkbox and the name is supposed to be unique.

    const columns = [
        {
            id: "select",
            header: ({ table }) => (
                <div className="transform translate-y-[5px]">
                    <CheckBoxButton 
                       checked={table.getIsAllPageRowsSelected()}
                       className="check-minus"
                       name="select"
                       onChange={table.getToggleAllRowsSelectedHandler()}
                    />
                </div>
            ),
            cell: ({ row }) => {
                return (
                    <div className="transform translate-y-[5px]">
                      <CheckBoxButton
                        checked={row.getIsSelected()}
                        name={`item-${row.id}`} // update here 
                        onChange {row.getToggleSelectedHandler()}
                        />
                    </div>
                );
            },
        },
    …
    ]