diff --git a/packages/ra-core/src/dataProvider/useGetList.spec.tsx b/packages/ra-core/src/dataProvider/useGetList.spec.tsx index 7556e6d673a..18f868b0b5c 100644 --- a/packages/ra-core/src/dataProvider/useGetList.spec.tsx +++ b/packages/ra-core/src/dataProvider/useGetList.spec.tsx @@ -344,6 +344,43 @@ describe('useGetList', () => { ).toEqual({ id: 1, title: 'live' }); }); + it('should not pre-populate getOne Query Cache if more than 100 results', async () => { + const callback: any = jest.fn(); + const queryClient = new QueryClient(); + const dataProvider: any = { + getList: jest.fn(() => + Promise.resolve({ + data: Array.from(Array(101).keys()).map(index => ({ + id: index + 1, + title: `item ${index + 1}`, + })), + total: 101, + }) + ), + }; + render( + + + + ); + await waitFor(() => { + expect(callback).toHaveBeenCalledWith( + expect.objectContaining({ + data: expect.arrayContaining([ + { id: 1, title: 'item 1' }, + { id: 101, title: 'item 101' }, + ]), + }) + ); + }); + expect( + queryClient.getQueryData(['posts', 'getOne', { id: '1' }]) + ).toBeUndefined(); + }); + it('should not fail when the query is disabled and the cache gets updated by another query', async () => { const callback: any = jest.fn(); const onSuccess = jest.fn(); diff --git a/packages/ra-core/src/dataProvider/useGetList.ts b/packages/ra-core/src/dataProvider/useGetList.ts index 27d5bb607b7..012d2a27181 100644 --- a/packages/ra-core/src/dataProvider/useGetList.ts +++ b/packages/ra-core/src/dataProvider/useGetList.ts @@ -9,6 +9,8 @@ import { import { RaRecord, GetListParams, GetListResult } from '../types'; import { useDataProvider } from './useDataProvider'; +const MAX_DATA_LENGTH_TO_CACHE = 100; + /** * Call the dataProvider.getList() method and return the resolved result * as well as the loading state. @@ -87,12 +89,21 @@ export const useGetList = ( ...options, onSuccess: value => { // optimistically populate the getOne cache - value?.data?.forEach(record => { - queryClient.setQueryData( - [resource, 'getOne', { id: String(record.id), meta }], - oldRecord => oldRecord ?? record - ); - }); + if ( + value?.data && + value.data.length <= MAX_DATA_LENGTH_TO_CACHE + ) { + value.data.forEach(record => { + queryClient.setQueryData( + [ + resource, + 'getOne', + { id: String(record.id), meta }, + ], + oldRecord => oldRecord ?? record + ); + }); + } // execute call-time onSuccess if provided if (options?.onSuccess) { options.onSuccess(value);