Skip to content

Commit 5680479

Browse files
authored
Merge pull request #6285 from marmelab/fix-context-identity-pref-regression
Fix performance regression causing unnecessary redraws
2 parents 374813f + 3190841 commit 5680479

10 files changed

+51
-50
lines changed

packages/ra-core/src/controller/details/useCreateContext.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useContext, useMemo } from 'react';
2-
import merge from 'lodash/merge';
2+
import defaults from 'lodash/defaults';
33

44
import { Record } from '../../types';
55
import { CreateContext } from './CreateContext';
@@ -35,10 +35,10 @@ export const useCreateContext = <
3535
// Props take precedence over the context
3636
return useMemo(
3737
() =>
38-
merge(
38+
defaults(
3939
{},
40-
context,
41-
props != null ? extractCreateContextProps(props) : {}
40+
props != null ? extractCreateContextProps(props) : {},
41+
context
4242
),
4343
[context, props]
4444
);

packages/ra-core/src/controller/details/useEditContext.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useContext, useMemo } from 'react';
2-
import merge from 'lodash/merge';
2+
import defaults from 'lodash/defaults';
33

44
import { Record } from '../../types';
55
import { EditContext } from './EditContext';
@@ -32,10 +32,10 @@ export const useEditContext = <RecordType extends Record = Record>(
3232
// Props take precedence over the context
3333
return useMemo(
3434
() =>
35-
merge(
35+
defaults(
3636
{},
37-
context,
38-
props != null ? extractEditContextProps(props) : {}
37+
props != null ? extractEditContextProps(props) : {},
38+
context
3939
),
4040
[context, props]
4141
);

packages/ra-core/src/controller/details/useShowContext.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useContext, useMemo } from 'react';
2-
import merge from 'lodash/merge';
2+
import defaults from 'lodash/defaults';
33

44
import { Record } from '../../types';
55
import { ShowContext } from './ShowContext';
@@ -32,10 +32,10 @@ export const useShowContext = <RecordType extends Record = Record>(
3232
// Props take precedence over the context
3333
return useMemo(
3434
() =>
35-
merge(
35+
defaults(
3636
{},
37-
context,
38-
props != null ? extractShowContextProps(props) : {}
37+
props != null ? extractShowContextProps(props) : {},
38+
context
3939
),
4040
[context, props]
4141
);

packages/ra-core/src/controller/input/useReferenceArrayInputContext.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useContext, useMemo } from 'react';
2-
import merge from 'lodash/merge';
2+
import defaults from 'lodash/defaults';
33
import {
44
ReferenceArrayInputContext,
55
ReferenceArrayInputContextValue,
@@ -17,12 +17,12 @@ export const useReferenceArrayInputContext = <
1717
// Props take precedence over the context
1818
return useMemo(
1919
() =>
20-
merge(
20+
defaults(
2121
{},
22-
context,
2322
props != null
2423
? extractReferenceArrayInputContextProps(props)
25-
: {}
24+
: {},
25+
context
2626
),
2727
[context, props]
2828
);

packages/ra-core/src/controller/useListContext.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useContext, useMemo } from 'react';
2-
import merge from 'lodash/merge';
2+
import defaults from 'lodash/defaults';
33

44
import ListContext from './ListContext';
55
import { ListControllerProps } from './useListController';
@@ -101,10 +101,10 @@ const useListContext = <RecordType extends Record = Record>(
101101
// @ts-ignore
102102
return useMemo(
103103
() =>
104-
merge(
104+
defaults(
105105
{},
106-
context,
107-
props != null ? extractListContextProps(props) : {}
106+
props != null ? extractListContextProps(props) : {},
107+
context
108108
),
109109
[context, props]
110110
);

packages/ra-core/src/controller/useRecordSelection.ts

+11-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback } from 'react';
1+
import { useMemo } from 'react';
22
import { useSelector, useDispatch, shallowEqual } from 'react-redux';
33
import { setListSelectedIds, toggleListItem } from '../actions/listActions';
44
import { Identifier, ReduxState } from '../types';
@@ -30,23 +30,20 @@ const useRecordSelection = (
3030
: defaultRecords,
3131
shallowEqual
3232
);
33-
const selectionModifiers = {
34-
select: useCallback(
35-
(newIds: Identifier[]) => {
33+
const selectionModifiers = useMemo(
34+
() => ({
35+
select: (newIds: Identifier[]) => {
3636
dispatch(setListSelectedIds(resource, newIds));
3737
},
38-
[resource] // eslint-disable-line react-hooks/exhaustive-deps
39-
),
40-
toggle: useCallback(
41-
(id: Identifier) => {
38+
toggle: (id: Identifier) => {
4239
dispatch(toggleListItem(resource, id));
4340
},
44-
[resource] // eslint-disable-line react-hooks/exhaustive-deps
45-
),
46-
clearSelection: useCallback(() => {
47-
dispatch(setListSelectedIds(resource, []));
48-
}, [resource]), // eslint-disable-line react-hooks/exhaustive-deps
49-
};
41+
clearSelection: () => {
42+
dispatch(setListSelectedIds(resource, []));
43+
},
44+
}),
45+
[dispatch, resource]
46+
);
5047

5148
return [selectedIds, selectionModifiers];
5249
};

packages/ra-core/src/core/useResourceDefinition.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useSelector } from 'react-redux';
2-
import merge from 'lodash/merge';
2+
import defaults from 'lodash/defaults';
33
import { getResources } from '../reducer';
44
import { ResourceDefinition } from '../types';
55
import { useResourceContext } from './useResourceContext';
@@ -17,12 +17,16 @@ export const useResourceDefinition = (
1717

1818
const definition = useMemo(() => {
1919
const definitionFromRedux = resources.find(r => r?.name === resource);
20-
return merge({}, definitionFromRedux, {
21-
hasCreate,
22-
hasEdit,
23-
hasList,
24-
hasShow,
25-
});
20+
return defaults(
21+
{},
22+
{
23+
hasCreate,
24+
hasEdit,
25+
hasList,
26+
hasShow,
27+
},
28+
definitionFromRedux
29+
);
2630
}, [resource, resources, hasCreate, hasEdit, hasList, hasShow]);
2731

2832
return definition;

packages/ra-core/src/dataProvider/useDataProvider.spec.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ describe('useDataProvider', () => {
422422
expect(update).toBeCalledTimes(1);
423423
// make sure the side effect hasn't been applied yet
424424
expect(queryByText('(updated)')).toBeNull();
425-
await act(() => {
425+
await act(async () => {
426426
resolveUpdate();
427427
});
428428
// side effects should be applied now
@@ -473,7 +473,7 @@ describe('useDataProvider', () => {
473473
// side effects should be applied now
474474
expect(queryByText('(updated)')).not.toBeNull();
475475
expect(update).toBeCalledTimes(1);
476-
await act(() => {
476+
act(() => {
477477
resolveUpdate();
478478
});
479479
});
@@ -521,7 +521,7 @@ describe('useDataProvider', () => {
521521
expect(queryByText('(updated)')).not.toBeNull();
522522
// update shouldn't be called at all
523523
expect(update).toBeCalledTimes(0);
524-
await act(() => {
524+
act(() => {
525525
undoableEventEmitter.emit('end', {});
526526
});
527527
expect(update).toBeCalledTimes(1);

packages/ra-ui-materialui/src/form/SimpleFormIterator.spec.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ describe('<SimpleFormIterator />', () => {
500500
});
501501

502502
it('should call the onClick method when the custom add button is clicked', async () => {
503-
const onClick = jest.fn();
503+
const onClick = jest.fn().mockImplementation(e => e.preventDefault());
504504
const { getByText } = renderWithRedux(
505505
<ThemeProvider theme={theme}>
506506
<SaveContextProvider value={saveContextValue}>
@@ -527,7 +527,7 @@ describe('<SimpleFormIterator />', () => {
527527
});
528528

529529
it('should call the onClick method when the custom remove button is clicked', async () => {
530-
const onClick = jest.fn();
530+
const onClick = jest.fn().mockImplementation(e => e.preventDefault());
531531
const { getByText } = renderWithRedux(
532532
<ThemeProvider theme={theme}>
533533
<SaveContextProvider value={saveContextValue}>

packages/ra-ui-materialui/src/list/datagrid/useDatagridContext.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useContext, useMemo } from 'react';
22
import { DatagridProps } from './Datagrid';
33
import DatagridContext, { DatagridContextValue } from './DatagridContext';
4-
import merge from 'lodash/merge';
4+
import defaults from 'lodash/defaults';
55

66
export const useDatagridContext = (
77
props?: DatagridProps
@@ -10,10 +10,10 @@ export const useDatagridContext = (
1010

1111
return useMemo(
1212
() =>
13-
merge(
13+
defaults(
1414
{},
15-
context,
16-
props != null ? { isRowExpandable: props.isRowExpandable } : {}
15+
props != null ? { isRowExpandable: props.isRowExpandable } : {},
16+
context
1717
),
1818
[context, props]
1919
);

0 commit comments

Comments
 (0)