Skip to content

Commit 39e2bef

Browse files
authored
Merge pull request #9359 from marmelab/fix-useGetList-big-data-cache-update
Fix `useGetList` optimistic cache update leads to ui freeze when too many records are returned
2 parents 1b2ba5c + 139133e commit 39e2bef

File tree

2 files changed

+54
-6
lines changed

2 files changed

+54
-6
lines changed

packages/ra-core/src/dataProvider/useGetList.spec.tsx

+37
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,43 @@ describe('useGetList', () => {
344344
).toEqual({ id: 1, title: 'live' });
345345
});
346346

347+
it('should not pre-populate getOne Query Cache if more than 100 results', async () => {
348+
const callback: any = jest.fn();
349+
const queryClient = new QueryClient();
350+
const dataProvider: any = {
351+
getList: jest.fn(() =>
352+
Promise.resolve({
353+
data: Array.from(Array(101).keys()).map(index => ({
354+
id: index + 1,
355+
title: `item ${index + 1}`,
356+
})),
357+
total: 101,
358+
})
359+
),
360+
};
361+
render(
362+
<CoreAdminContext
363+
queryClient={queryClient}
364+
dataProvider={dataProvider}
365+
>
366+
<UseGetList callback={callback} />
367+
</CoreAdminContext>
368+
);
369+
await waitFor(() => {
370+
expect(callback).toHaveBeenCalledWith(
371+
expect.objectContaining({
372+
data: expect.arrayContaining([
373+
{ id: 1, title: 'item 1' },
374+
{ id: 101, title: 'item 101' },
375+
]),
376+
})
377+
);
378+
});
379+
expect(
380+
queryClient.getQueryData(['posts', 'getOne', { id: '1' }])
381+
).toBeUndefined();
382+
});
383+
347384
it('should not fail when the query is disabled and the cache gets updated by another query', async () => {
348385
const callback: any = jest.fn();
349386
const onSuccess = jest.fn();

packages/ra-core/src/dataProvider/useGetList.ts

+17-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import {
99
import { RaRecord, GetListParams, GetListResult } from '../types';
1010
import { useDataProvider } from './useDataProvider';
1111

12+
const MAX_DATA_LENGTH_TO_CACHE = 100;
13+
1214
/**
1315
* Call the dataProvider.getList() method and return the resolved result
1416
* as well as the loading state.
@@ -87,12 +89,21 @@ export const useGetList = <RecordType extends RaRecord = any>(
8789
...options,
8890
onSuccess: value => {
8991
// optimistically populate the getOne cache
90-
value?.data?.forEach(record => {
91-
queryClient.setQueryData(
92-
[resource, 'getOne', { id: String(record.id), meta }],
93-
oldRecord => oldRecord ?? record
94-
);
95-
});
92+
if (
93+
value?.data &&
94+
value.data.length <= MAX_DATA_LENGTH_TO_CACHE
95+
) {
96+
value.data.forEach(record => {
97+
queryClient.setQueryData(
98+
[
99+
resource,
100+
'getOne',
101+
{ id: String(record.id), meta },
102+
],
103+
oldRecord => oldRecord ?? record
104+
);
105+
});
106+
}
96107
// execute call-time onSuccess if provided
97108
if (options?.onSuccess) {
98109
options.onSuccess(value);

0 commit comments

Comments
 (0)