From 55612b8f934270f24731577a9c698eb4a5a46fbf Mon Sep 17 00:00:00 2001 From: fzaninotto Date: Mon, 30 Nov 2020 22:45:52 +0100 Subject: [PATCH 1/4] Fix useless rerenders in List page --- examples/simple/src/posts/PostList.js | 4 +++- .../field/useReferenceArrayFieldController.ts | 3 ++- packages/ra-core/src/core/CoreAdminUI.tsx | 12 ++++++++++-- packages/ra-ui-materialui/src/field/BooleanField.tsx | 11 +++++++++-- packages/ra-ui-materialui/src/layout/AppBar.tsx | 4 ++-- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/examples/simple/src/posts/PostList.js b/examples/simple/src/posts/PostList.js index bee73d1c606..26cff684828 100644 --- a/examples/simple/src/posts/PostList.js +++ b/examples/simple/src/posts/PostList.js @@ -160,7 +160,7 @@ const PostList = props => { reference="tags" source="tags" sortBy="tags.name" - sort={{ field: 'name', order: 'ASC' }} + sort={tagSort} cellClassName={classes.hiddenOnSmallScreens} headerClassName={classes.hiddenOnSmallScreens} > @@ -178,4 +178,6 @@ const PostList = props => { ); }; +const tagSort = { field: 'name', order: 'ASC' }; + export default PostList; diff --git a/packages/ra-core/src/controller/field/useReferenceArrayFieldController.ts b/packages/ra-core/src/controller/field/useReferenceArrayFieldController.ts index 643388f6092..7a848ab6770 100644 --- a/packages/ra-core/src/controller/field/useReferenceArrayFieldController.ts +++ b/packages/ra-core/src/controller/field/useReferenceArrayFieldController.ts @@ -24,6 +24,7 @@ interface Option { source: string; } +const emptyArray = []; const defaultFilter = {}; const defaultSort = { field: null, order: null }; @@ -65,7 +66,7 @@ const useReferenceArrayFieldController = ( } = props; const resource = useResourceContext(props); const notify = useNotify(); - const ids = get(record, source) || []; + const ids = get(record, source) || emptyArray; const { data, error, loading, loaded } = useGetMany(reference, ids, { onFailure: error => notify( diff --git a/packages/ra-core/src/core/CoreAdminUI.tsx b/packages/ra-core/src/core/CoreAdminUI.tsx index eb3a4d9bbfe..246edca874a 100644 --- a/packages/ra-core/src/core/CoreAdminUI.tsx +++ b/packages/ra-core/src/core/CoreAdminUI.tsx @@ -1,5 +1,10 @@ import * as React from 'react'; -import { createElement, FunctionComponent, ComponentType } from 'react'; +import { + createElement, + FunctionComponent, + ComponentType, + useMemo, +} from 'react'; import { Switch, Route } from 'react-router-dom'; import CoreAdminRouter from './CoreAdminRouter'; @@ -54,6 +59,9 @@ const CoreAdminUI: FunctionComponent = ({ theme, title = 'React Admin', }) => { + const logoutElement = React.useMemo(() => logout && createElement(logout), [ + logout, + ]); return ( {loginPage !== false && loginPage !== true ? ( @@ -78,7 +86,7 @@ const CoreAdminUI: FunctionComponent = ({ dashboard={dashboard} layout={layout} loading={loading} - logout={logout && createElement(logout)} + logout={logoutElement} menu={menu} ready={ready} theme={theme} diff --git a/packages/ra-ui-materialui/src/field/BooleanField.tsx b/packages/ra-ui-materialui/src/field/BooleanField.tsx index bc01f197697..4f22e7b36d7 100644 --- a/packages/ra-ui-materialui/src/field/BooleanField.tsx +++ b/packages/ra-ui-materialui/src/field/BooleanField.tsx @@ -59,9 +59,16 @@ export const BooleanField: FC = memo( > {value === true ? ( - + + + ) : ( - + + + )} diff --git a/packages/ra-ui-materialui/src/layout/AppBar.tsx b/packages/ra-ui-materialui/src/layout/AppBar.tsx index a6c758e3f18..e963423be63 100644 --- a/packages/ra-ui-materialui/src/layout/AppBar.tsx +++ b/packages/ra-ui-materialui/src/layout/AppBar.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Children, cloneElement } from 'react'; +import { Children, cloneElement, memo } from 'react'; import PropTypes from 'prop-types'; import { useDispatch } from 'react-redux'; import classNames from 'classnames'; @@ -195,4 +195,4 @@ export interface AppBarProps extends Omit { userMenu?: JSX.Element | boolean; } -export default AppBar; +export default memo(AppBar); From 6a158e5695c393f6c8c887c93758bc8d0761d5c7 Mon Sep 17 00:00:00 2001 From: fzaninotto Date: Wed, 2 Dec 2020 08:57:53 +0100 Subject: [PATCH 2/4] Avoid Appbar rerenders --- examples/simple/src/Layout.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/simple/src/Layout.js b/examples/simple/src/Layout.js index 5ec04df5fdf..e9f6fe04037 100644 --- a/examples/simple/src/Layout.js +++ b/examples/simple/src/Layout.js @@ -1,5 +1,5 @@ import * as React from 'react'; -import { forwardRef } from 'react'; +import { forwardRef, memo } from 'react'; import { Layout, AppBar, UserMenu, useLocale, useSetLocale } from 'react-admin'; import { MenuItem, ListItemIcon } from '@material-ui/core'; import { makeStyles } from '@material-ui/core/styles'; @@ -39,6 +39,6 @@ const MyUserMenu = props => ( ); -const MyAppBar = props => } />; +const MyAppBar = memo(props => } />); export default props => ; From c3eb787346b043cf712742ebb5e8e481ed88c721 Mon Sep 17 00:00:00 2001 From: fzaninotto Date: Wed, 2 Dec 2020 11:29:36 +0100 Subject: [PATCH 3/4] Fix failing test --- .../ra-ui-materialui/src/field/BooleanField.spec.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/ra-ui-materialui/src/field/BooleanField.spec.tsx b/packages/ra-ui-materialui/src/field/BooleanField.spec.tsx index 69789b74841..3615f82efd1 100644 --- a/packages/ra-ui-materialui/src/field/BooleanField.spec.tsx +++ b/packages/ra-ui-materialui/src/field/BooleanField.spec.tsx @@ -15,7 +15,10 @@ describe('', () => { it('should display tick and truthy text if value is true', () => { const { queryByTitle } = render(); expect(queryByTitle('ra.boolean.true')).not.toBeNull(); - expect(queryByTitle('ra.boolean.true').dataset.testid).toBe('true'); + expect( + (queryByTitle('ra.boolean.true').firstChild as HTMLElement).dataset + .testid + ).toBe('true'); expect(queryByTitle('ra.boolean.false')).toBeNull(); }); @@ -39,7 +42,10 @@ describe('', () => { ); expect(queryByTitle('ra.boolean.true')).toBeNull(); expect(queryByTitle('ra.boolean.false')).not.toBeNull(); - expect(queryByTitle('ra.boolean.false').dataset.testid).toBe('false'); + expect( + (queryByTitle('ra.boolean.false').firstChild as HTMLElement).dataset + .testid + ).toBe('false'); }); it('should use valueLabelFalse for custom falsy text', () => { From c3ed4226cde1b08525f4006d3b5e2f7d09790624 Mon Sep 17 00:00:00 2001 From: fzaninotto Date: Wed, 2 Dec 2020 11:30:29 +0100 Subject: [PATCH 4/4] Fix warning --- packages/ra-core/src/core/CoreAdminUI.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ra-core/src/core/CoreAdminUI.tsx b/packages/ra-core/src/core/CoreAdminUI.tsx index 246edca874a..2a956fb9689 100644 --- a/packages/ra-core/src/core/CoreAdminUI.tsx +++ b/packages/ra-core/src/core/CoreAdminUI.tsx @@ -59,7 +59,7 @@ const CoreAdminUI: FunctionComponent = ({ theme, title = 'React Admin', }) => { - const logoutElement = React.useMemo(() => logout && createElement(logout), [ + const logoutElement = useMemo(() => logout && createElement(logout), [ logout, ]); return (