fix(data-table): capture row selection state in memo comparison (#5524)
Merge pull request #5524 from RedwindA/fix/channelCheckbox
This commit is contained in:
@@ -29,15 +29,20 @@ type DataTableRowProps<TData> = {
|
||||
getColumnClassName?: DataTableColumnClassName
|
||||
} & Omit<React.ComponentProps<typeof TableRow>, 'children'>
|
||||
|
||||
type DataTableRowInnerProps<TData> = DataTableRowProps<TData> & {
|
||||
isSelected: boolean
|
||||
}
|
||||
|
||||
function DataTableRowInner<TData>({
|
||||
row,
|
||||
isSelected,
|
||||
className,
|
||||
getColumnClassName,
|
||||
...rowProps
|
||||
}: DataTableRowProps<TData>) {
|
||||
}: DataTableRowInnerProps<TData>) {
|
||||
return (
|
||||
<TableRow
|
||||
data-state={row.getIsSelected() ? 'selected' : undefined}
|
||||
data-state={isSelected ? 'selected' : undefined}
|
||||
className={className}
|
||||
{...rowProps}
|
||||
>
|
||||
@@ -56,17 +61,23 @@ function DataTableRowInner<TData>({
|
||||
)
|
||||
}
|
||||
|
||||
export const DataTableRow = React.memo(DataTableRowInner, (prev, next) => {
|
||||
// Skip re-render when only the getColumnClassName reference changed but the
|
||||
// row identity and selection state are the same — callers rarely stabilize
|
||||
// this callback, so excluding it from comparison avoids unnecessary renders.
|
||||
const MemoizedDataTableRow = React.memo(DataTableRowInner, (prev, next) => {
|
||||
// Do not read row.getIsSelected() here: TanStack row objects may keep a stable
|
||||
// reference while their selection state changes.
|
||||
return (
|
||||
prev.row === next.row &&
|
||||
prev.className === next.className &&
|
||||
prev.row.getIsSelected() === next.row.getIsSelected()
|
||||
prev.getColumnClassName === next.getColumnClassName &&
|
||||
prev.isSelected === next.isSelected
|
||||
)
|
||||
}) as typeof DataTableRowInner
|
||||
|
||||
export function DataTableRow<TData>(props: DataTableRowProps<TData>) {
|
||||
return (
|
||||
<MemoizedDataTableRow {...props} isSelected={props.row.getIsSelected()} />
|
||||
)
|
||||
}
|
||||
|
||||
function renderCellContent<TData>(cell: Cell<TData, unknown>) {
|
||||
const content = flexRender(cell.column.columnDef.cell, cell.getContext())
|
||||
const textContent = getPrimitiveTextContent(content)
|
||||
|
||||
Reference in New Issue
Block a user