From 2b00a31d4d0f2aa183dbe7e9d8558ea619252a2d Mon Sep 17 00:00:00 2001 From: Ben Wittenberg Date: Tue, 4 Jun 2024 19:13:26 +0000 Subject: [PATCH] chore: spike - improve performance with early return --- packages/react/src/DataTable/DataTable.tsx | 6 +- .../DataTable/__tests__/DataTable.test.tsx | 63 ++++++++++++++++++- packages/react/src/DataTable/useTable.ts | 9 ++- 3 files changed, 73 insertions(+), 5 deletions(-) diff --git a/packages/react/src/DataTable/DataTable.tsx b/packages/react/src/DataTable/DataTable.tsx index e2d59e171a96..7f89c545fb91 100644 --- a/packages/react/src/DataTable/DataTable.tsx +++ b/packages/react/src/DataTable/DataTable.tsx @@ -61,13 +61,17 @@ function DataTable({ initialSortColumn, initialSortDirection, }: DataTableProps) { - const {headers, rows, actions, gridTemplateColumns} = useTable({ + const {headers, rows, actions, gridTemplateColumns, willReactThrowOutRenderResult} = useTable({ data, columns, initialSortColumn, initialSortDirection, }) + if (willReactThrowOutRenderResult) { + return null + } + return ( { expect(customSortFn).toHaveBeenCalled() expect(getCellContentByColumnHeaderName('Value')).toEqual(['3', '2', '1']) }) + + it('should sort again when data changes', async () => { + type Data = {id: string; value: string} + const columns: ComponentProps>['columns'] = [ + { + header: 'Value', + field: 'value', + sortBy: true, + }, + ] + const data: ComponentProps>['data'] = [ + { + id: '3', + value: '3', + }, + { + id: '2', + value: '2', + }, + ] + const {rerender} = render( + , + ) + + rerender( + , + ) + + expect(getCellContentByColumnHeaderName('Value')).toEqual(['1', '2', '3']) + }) }) describe('column widths', () => { @@ -1036,4 +1071,30 @@ describe('DataTable', () => { }) }) }) + + describe('performance tests', () => { + it('should not render twice on initial render', () => { + type Data = {id: string; value: string} + const columns: ComponentProps>['columns'] = [ + { + header: 'Value', + field: 'value', + }, + ] + const data: ComponentProps>['data'] = [ + { + id: '1', + value: 'one', + }, + ] + let renderCount = 0 + render( + renderCount++}> + + , + ) + + expect(renderCount).toBe(1) + }) + }) }) diff --git a/packages/react/src/DataTable/useTable.ts b/packages/react/src/DataTable/useTable.ts index d046f736e88e..a85d73897d26 100644 --- a/packages/react/src/DataTable/useTable.ts +++ b/packages/react/src/DataTable/useTable.ts @@ -47,7 +47,7 @@ export function useTable({ data, initialSortColumn, initialSortDirection, -}: TableConfig): Table { +}: TableConfig): Table & {willReactThrowOutRenderResult: boolean} { const [rowOrder, setRowOrder] = useState(data) const [prevData, setPrevData] = useState(null) const [prevColumns, setPrevColumns] = useState(columns) @@ -58,7 +58,8 @@ export function useTable({ // Reset the `sortByColumn` state if the columns change and that column is no // longer provided - if (columns !== prevColumns) { + const haveColumnsChanged = columns !== prevColumns + if (haveColumnsChanged) { setPrevColumns(columns) if (sortByColumn) { const column = columns.find(column => { @@ -94,7 +95,8 @@ export function useTable({ }) // Update the row order and apply the current sort column to the incoming data - if (data !== prevData) { + const hasDataChanged = data !== prevData + if (hasDataChanged) { setPrevData(data) setRowOrder(data) if (sortByColumn) { @@ -207,6 +209,7 @@ export function useTable({ sortBy, }, gridTemplateColumns, + willReactThrowOutRenderResult: hasDataChanged || haveColumnsChanged, } }