From fa570edb128dcd54896bc133943fcca84c424cde Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Fri, 21 Feb 2025 12:13:32 +0200 Subject: [PATCH] fix: Allow useGridDataProvider to use an inline function Assumes the useGridDataProvider list function does not change so that the method can be defined inline without constantly reassigning the data provider and reloading all data --- packages/ts/react-crud/src/data-provider.ts | 12 +++++++++--- packages/ts/react-crud/test/dataprovider.spec.tsx | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/packages/ts/react-crud/src/data-provider.ts b/packages/ts/react-crud/src/data-provider.ts index e2cce61547..e3251fe669 100644 --- a/packages/ts/react-crud/src/data-provider.ts +++ b/packages/ts/react-crud/src/data-provider.ts @@ -1,5 +1,4 @@ -import type { GridDataProviderCallback, GridDataProviderParams } from '@vaadin/react-components/Grid'; -import type { GridDataProvider } from '@vaadin/react-components/Grid'; +import type { GridDataProvider, GridDataProviderCallback, GridDataProviderParams } from '@vaadin/react-components/Grid'; import { useMemo, useState } from 'react'; import type { CountService, ListService } from './crud'; import type FilterUnion from './types/com/vaadin/hilla/crud/filter/FilterUnion'; @@ -220,7 +219,14 @@ export type UseGridDataProviderResult = GridDataProvider & { export type GridFetchCallback = (pageable: Pageable) => Promise; export function useGridDataProvider(list: GridFetchCallback): UseGridDataProviderResult { - const result = useDataProvider({ list: async (pageable) => list(pageable) }); + const result = useDataProvider( + useMemo( + () => ({ + list: async (pageable: Pageable) => list(pageable), + }), + [], + ), + ); const dataProvider: UseGridDataProviderResult = result.dataProvider as UseGridDataProviderResult; dataProvider.refresh = result.refresh; return dataProvider; diff --git a/packages/ts/react-crud/test/dataprovider.spec.tsx b/packages/ts/react-crud/test/dataprovider.spec.tsx index c80b138b0a..5f9926a7a9 100644 --- a/packages/ts/react-crud/test/dataprovider.spec.tsx +++ b/packages/ts/react-crud/test/dataprovider.spec.tsx @@ -11,6 +11,7 @@ import { InfiniteDataProvider, useDataProvider, useGridDataProvider, + type GridFetchCallback, type ItemCounts, } from '../src/data-provider.js'; import type AndFilter from '../src/types/com/vaadin/hilla/crud/filter/AndFilter.js'; @@ -263,6 +264,20 @@ describe('@hilla/react-crud', () => { await grid.requestPage(0); expect(called).to.be.equal(1); }); + it('does not reassign data provider for an inline fetch function', async () => { + const method1 = async (_pageable: Pageable) => await Promise.resolve([{ id: 1, name: 'Product 1' }]); + const method2 = async (_pageable: Pageable) => await Promise.resolve([{ id: 2, name: 'Product 2' }]); + type PropsType = { fetchCallback: GridFetchCallback }; + + const hook = renderHook((props: PropsType) => useGridDataProvider(props.fetchCallback), { + initialProps: { fetchCallback: method1 }, + }); + + const dataprovider1 = hook.result.current; + hook.rerender({ fetchCallback: method2 }); + const dataprovider2 = hook.result.current; + expect(dataprovider1).to.be.eq(dataprovider2); + }); }); describe('createDataProvider', () => {