Commit 743520d5 by 同語 Committed by GitHub

Merge branch 'main' into fix/channel-test-dialog-status-refresh

parents 24488773 b4176de8
...@@ -35,18 +35,25 @@ type DataTableRowProps<TData> = { ...@@ -35,18 +35,25 @@ type DataTableRowProps<TData> = {
cellRenderColumns?: TanstackTable<TData>['options']['columns'] cellRenderColumns?: TanstackTable<TData>['options']['columns']
} & Omit<React.ComponentProps<typeof TableRow>, 'children'> } & Omit<React.ComponentProps<typeof TableRow>, 'children'>
type DataTableRowInnerProps<TData> = DataTableRowProps<TData> & {
isSelected: boolean
}
function DataTableRowInner<TData>({ function DataTableRowInner<TData>({
row, row,
isSelected,
className, className,
getColumnClassName, getColumnClassName,
cellRenderColumns, cellRenderColumns,
...rowProps ...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 void cellRenderColumns
return ( return (
<TableRow <TableRow
data-state={row.getIsSelected() ? 'selected' : undefined} data-state={isSelected ? 'selected' : undefined}
className={className} className={className}
{...rowProps} {...rowProps}
> >
...@@ -65,20 +72,30 @@ function DataTableRowInner<TData>({ ...@@ -65,20 +72,30 @@ function DataTableRowInner<TData>({
) )
} }
export const DataTableRow = React.memo(DataTableRowInner, (prev, next) => { const MemoizedDataTableRow = React.memo(DataTableRowInner, (prev, next) => {
// Skip re-render when only the getColumnClassName reference changed but the // Do not read row.getIsSelected() inside the comparator: TanStack row objects
// row identity and selection state are the same — callers rarely stabilize // keep a stable reference while their selection state mutates, so reading it
// this callback, so excluding it from comparison avoids unnecessary renders. // here compares identical live values and misses selection changes. Selection
// Column cell renderers can close over external state while the row stays // is lifted to the `isSelected` prop, captured per render in DataTableRow.
// stable, so column definitions are part of the render identity. //
// 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 ( return (
prev.row === next.row && prev.row === next.row &&
prev.className === next.className && prev.className === next.className &&
prev.row.getIsSelected() === next.row.getIsSelected() && prev.isSelected === next.isSelected &&
prev.getColumnClassName === next.getColumnClassName &&
prev.cellRenderColumns === next.cellRenderColumns prev.cellRenderColumns === next.cellRenderColumns
) )
}) as typeof DataTableRowInner }) as typeof DataTableRowInner
export function DataTableRow<TData>(props: DataTableRowProps<TData>) {
return (
<MemoizedDataTableRow {...props} isSelected={props.row.getIsSelected()} />
)
}
function renderCellContent<TData>(cell: Cell<TData, unknown>) { function renderCellContent<TData>(cell: Cell<TData, unknown>) {
const content = flexRender(cell.column.columnDef.cell, cell.getContext()) const content = flexRender(cell.column.columnDef.cell, cell.getContext())
const textContent = getPrimitiveTextContent(content) const textContent = getPrimitiveTextContent(content)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment