diff --git a/packages/table-core/__tests__/CachedValue.test.ts b/packages/table-core/__tests__/CachedValue.test.ts new file mode 100644 index 0000000000..2445357078 --- /dev/null +++ b/packages/table-core/__tests__/CachedValue.test.ts @@ -0,0 +1,56 @@ +import { ColumnDef, getCoreRowModel } from '../src' +import { createColumnHelper } from '../src/columnHelper' +import { createTable } from '../src/core/table' +import { getGroupedRowModel } from '../src/utils/getGroupedRowModel' +import { makeData, Person } from './makeTestData' + +type personKeys = keyof Person +type PersonColumn = ColumnDef +const columnHelper = createColumnHelper() + +describe('#CachedValue', () => { + it('cached value invalidated after changing accessorFn', () => { + const data = makeData(1) + + const targetColumnId = 'name' + + const table = createTable({ + data, + columns: [ + columnHelper.accessor(() => 'hoge', { + id: targetColumnId, + }), + ], + onStateChange() {}, + renderFallbackValue: '', + state: {}, + getCoreRowModel: getCoreRowModel(), + getGroupedRowModel: getGroupedRowModel(), + }) + + const row = table.getCoreRowModel().rows[0] + expect(row.getValue(targetColumnId)).toBe('hoge') + + let execCounter = 0 + table.setOptions(old => { + return { + ...old, + columns: [ + columnHelper.accessor( + () => { + execCounter = execCounter + 1 + return 'fuga' + }, + { + id: targetColumnId, + } + ), + ], + } + }) + + expect(row.getValue(targetColumnId)).toBe('fuga') + row.getValue(targetColumnId) + expect(execCounter).toBe(1) + }) +}) diff --git a/packages/table-core/src/core/row.ts b/packages/table-core/src/core/row.ts index 0af28aa94c..ad156bafd5 100644 --- a/packages/table-core/src/core/row.ts +++ b/packages/table-core/src/core/row.ts @@ -1,4 +1,4 @@ -import { RowData, Cell, Row, Table } from '../types' +import { Cell, Row, RowData, Table } from '../types' import { flattenBy, getMemoOptions, memo } from '../utils' import { createCell } from './cell' @@ -6,6 +6,7 @@ export interface CoreRow { _getAllCellsByColumnId: () => Record> _uniqueValuesCache: Record _valuesCache: Record + _accessorFnsCache: Record /** * The depth of the row (if nested or grouped) relative to the root row array. * @link [API Docs](https://tanstack.com/table/v8/docs/api/core/row#depth) @@ -107,19 +108,24 @@ export const createRow = ( original, depth, parentId, + _accessorFnsCache: {}, _valuesCache: {}, _uniqueValuesCache: {}, getValue: columnId => { - if (row._valuesCache.hasOwnProperty(columnId)) { + const column = table.getColumn(columnId) + if ( + row._valuesCache.hasOwnProperty(columnId) && + row._accessorFnsCache.hasOwnProperty(columnId) && + row._accessorFnsCache[columnId] === column?.accessorFn + ) { return row._valuesCache[columnId] } - const column = table.getColumn(columnId) - if (!column?.accessorFn) { return undefined } + row._accessorFnsCache[columnId] = column.accessorFn row._valuesCache[columnId] = column.accessorFn( row.original as TData, rowIndex @@ -128,12 +134,15 @@ export const createRow = ( return row._valuesCache[columnId] as any }, getUniqueValues: columnId => { - if (row._uniqueValuesCache.hasOwnProperty(columnId)) { + const column = table.getColumn(columnId) + if ( + row._uniqueValuesCache.hasOwnProperty(columnId) && + row._accessorFnsCache.hasOwnProperty(columnId) && + row._accessorFnsCache[columnId] === column?.accessorFn + ) { return row._uniqueValuesCache[columnId] } - const column = table.getColumn(columnId) - if (!column?.accessorFn) { return undefined } @@ -143,6 +152,7 @@ export const createRow = ( return row._uniqueValuesCache[columnId] } + row._accessorFnsCache[columnId] = column.accessorFn row._uniqueValuesCache[columnId] = column.columnDef.getUniqueValues( row.original as TData, rowIndex