Merge branch 'main' into fix/channel-test-dialog-status-refresh
This commit is contained in:
+27
-10
@@ -35,18 +35,25 @@ type DataTableRowProps<TData> = {
|
||||
cellRenderColumns?: TanstackTable<TData>['options']['columns']
|
||||
} & Omit<React.ComponentProps<typeof TableRow>, 'children'>
|
||||
|
||||
type DataTableRowInnerProps<TData> = DataTableRowProps<TData> & {
|
||||
isSelected: boolean
|
||||
}
|
||||
|
||||
function DataTableRowInner<TData>({
|
||||
row,
|
||||
isSelected,
|
||||
className,
|
||||
getColumnClassName,
|
||||
cellRenderColumns,
|
||||
...rowProps
|
||||
}: DataTableRowProps<TData>) {
|
||||
}: DataTableRowInnerProps<TData>) {
|
||||
// Destructured only to keep it out of `rowProps` (it is not a valid DOM attr)
|
||||
// and to feed the memo comparator below; it is intentionally unused here.
|
||||
void cellRenderColumns
|
||||
|
||||
return (
|
||||
<TableRow
|
||||
data-state={row.getIsSelected() ? 'selected' : undefined}
|
||||
data-state={isSelected ? 'selected' : undefined}
|
||||
className={className}
|
||||
{...rowProps}
|
||||
>
|
||||
@@ -65,20 +72,30 @@ 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.
|
||||
// Column cell renderers can close over external state while the row stays
|
||||
// stable, so column definitions are part of the render identity.
|
||||
const MemoizedDataTableRow = React.memo(DataTableRowInner, (prev, next) => {
|
||||
// Do not read row.getIsSelected() inside the comparator: TanStack row objects
|
||||
// keep a stable reference while their selection state mutates, so reading it
|
||||
// here compares identical live values and misses selection changes. Selection
|
||||
// is lifted to the `isSelected` prop, captured per render in DataTableRow.
|
||||
//
|
||||
// Column cell renderers (and getColumnClassName) can close over external
|
||||
// state while the row stays stable, so column definitions and the class
|
||||
// resolver are part of the render identity and must be compared too.
|
||||
return (
|
||||
prev.row === next.row &&
|
||||
prev.className === next.className &&
|
||||
prev.row.getIsSelected() === next.row.getIsSelected() &&
|
||||
prev.isSelected === next.isSelected &&
|
||||
prev.getColumnClassName === next.getColumnClassName &&
|
||||
prev.cellRenderColumns === next.cellRenderColumns
|
||||
)
|
||||
}) 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)
|
||||
@@ -102,4 +119,4 @@ function getPrimitiveTextContent(content: React.ReactNode): string | null {
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user