Row interactions
Use onRowClicked to respond when a user clicks a row. The handler receives the
row data and the original React.MouseEvent, so you can inspect modifier keys,
navigate programmatically, or open a detail panel.
Row click: detail panel
Click any row to display its details below the table.
import { useState } from 'react';
import DataTable, { type TableColumn } from 'react-data-table-component';
interface Employee {
id: number; name: string; department: string; role: string; email: string;
}
const columns: TableColumn<Employee>[] = [
{ name: 'Name', selector: r => r.name, sortable: true },
{ name: 'Department', selector: r => r.department, sortable: true },
{ name: 'Role', selector: r => r.role },
];
export default function App() {
const [selected, setSelected] = useState<Employee | null>(null);
return (
<div>
<DataTable
columns={columns}
data={data}
pointerOnHover
highlightOnHover
onRowClicked={row => setSelected(row)}
/>
{selected && (
<div>{selected.name} — {selected.role}, {selected.department}</div>
)}
</div>
);
} Rows as navigation links
When rows represent records you navigate to, pass a URL to your router inside
onRowClicked. Check e.ctrlKey or e.metaKey to open in a
new tab on Ctrl/⌘+click.
For cells that should behave as independent links (email, external URL), set
ignoreRowClick: true on the column so clicks there don't also fire
onRowClicked.
Use onRowMiddleClicked to handle middle-click (scroll-click). Combined with
onRowClicked, you get full NavLink behaviour: left-click navigates in the same tab,
middle-click or Ctrl/⌘+click opens in a new tab.
Row navigation: left, middle, and Ctrl/⌘ click
Left-click navigates in the same tab. Middle-click or Ctrl/⌘+click opens in a new tab. The Email column is an independent link.
Click a row to navigate. Ctrl/⌘+click to open in new tab. Email cells are independent links.
import DataTable, { type TableColumn } from 'react-data-table-component';
import { useNavigate } from 'react-router-dom'; // or your router
const columns: TableColumn<Employee>[] = [
{ name: 'Name', selector: r => r.name },
{ name: 'Department', selector: r => r.department },
{ name: 'Role', selector: r => r.role },
{
name: 'Email',
ignoreRowClick: true,
cell: row => (
<a href={`mailto:${row.email}`} onClick={e => e.stopPropagation()}>
{row.email}
</a>
),
},
];
export default function App() {
const navigate = useNavigate();
return (
<DataTable
columns={columns}
data={data}
pointerOnHover
highlightOnHover
onRowClicked={(row, e) => {
if (e.ctrlKey || e.metaKey) {
window.open(`/employees/${row.id}`, '_blank');
} else {
navigate(`/employees/${row.id}`);
}
}}
onRowMiddleClicked={(row) => {
window.open(`/employees/${row.id}`, '_blank');
}}
/>
);
} Action buttons in cells
Use button: true on a column to add action controls that fire independently of
row clicks. The button prop centers the cell content and suppresses
onRowClicked for that column automatically. No need to call
e.stopPropagation() manually.
Per-row action buttons
Edit and Delete buttons fire their own handlers. Clicking elsewhere on the row still fires onRowClicked.
Action buttons fire independently. Clicking the row itself fires onRowClicked.
import DataTable, { type TableColumn } from 'react-data-table-component';
const columns: TableColumn<Employee>[] = [
{ name: 'Name', selector: r => r.name, sortable: true },
{ name: 'Department', selector: r => r.department, sortable: true },
{ name: 'Role', selector: r => r.role },
{
name: 'Actions',
button: true,
cell: row => (
<div style={{ display: 'flex', gap: 6 }}>
<button onClick={() => handleEdit(row)}>Edit</button>
<button onClick={() => handleDelete(row)}>Delete</button>
</div>
),
},
];
export default function App() {
return (
<DataTable
columns={columns}
data={data}
pointerOnHover
highlightOnHover
onRowClicked={row => console.log('row clicked', row.id)}
/>
);
}