From 1ab247128c79d4c454fe0ed692cc6a77b5ccf0ba Mon Sep 17 00:00:00 2001 From: djhi <1122076+djhi@users.noreply.github.com> Date: Fri, 28 Feb 2020 16:57:37 +0100 Subject: [PATCH] Add cache to usePermissions to avoid uncessessary render --- examples/simple/src/posts/PostList.js | 6 ++++++ .../ra-core/src/auth/usePermissions.spec.tsx | 18 ++++++++++++++++++ packages/ra-core/src/auth/usePermissions.ts | 10 +++++++++- .../src/button/BulkDeleteWithUndoButton.tsx | 6 ++++-- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/examples/simple/src/posts/PostList.js b/examples/simple/src/posts/PostList.js index 26cff684828..97cace4b7f7 100644 --- a/examples/simple/src/posts/PostList.js +++ b/examples/simple/src/posts/PostList.js @@ -13,6 +13,7 @@ import { ChipField, Datagrid, DateField, + DeleteButton, downloadCSV, EditButton, Filter, @@ -171,6 +172,11 @@ const PostList = props => { + + )} diff --git a/packages/ra-core/src/auth/usePermissions.spec.tsx b/packages/ra-core/src/auth/usePermissions.spec.tsx index c270db73d6f..65967d72e49 100644 --- a/packages/ra-core/src/auth/usePermissions.spec.tsx +++ b/packages/ra-core/src/auth/usePermissions.spec.tsx @@ -20,6 +20,12 @@ const stateInpector = state => ( ); +let renderCount = 0; +const renderInspector = () => { + renderCount++; + return
{renderCount}
; +}; + describe('usePermissions', () => { it('should return a loading state on mount', () => { const { queryByText } = renderWithRedux( @@ -79,4 +85,16 @@ describe('usePermissions', () => { expect(queryByText('ERROR')).not.toBeNull(); }); }); + + it('should not rerender once the permissions have been rertieved once', async () => { + const { queryByText, rerender } = renderWithRedux( + {renderInspector} + ); + + await new Promise(resolve => setTimeout(resolve, 10)); + expect(queryByText('2')).not.toBeNull(); + + rerender({renderInspector}); + expect(queryByText('3')).not.toBeNull(); + }); }); diff --git a/packages/ra-core/src/auth/usePermissions.ts b/packages/ra-core/src/auth/usePermissions.ts index 7c345d847ae..42ba93bf925 100644 --- a/packages/ra-core/src/auth/usePermissions.ts +++ b/packages/ra-core/src/auth/usePermissions.ts @@ -12,6 +12,8 @@ interface State { const emptyParams = {}; +const cache = {}; + /** * Hook for getting user permissions * @@ -43,14 +45,20 @@ const emptyParams = {}; * }; */ const usePermissions = (params = emptyParams) => { + const cacheKey = JSON.stringify(params); + const [state, setState] = useSafeSetState({ loading: true, loaded: false, + permissions: cache[cacheKey], }); + const getPermissions = useGetPermissions(); + useEffect(() => { getPermissions(params) .then(permissions => { + cache[cacheKey] = permissions; setState({ loading: false, loaded: true, permissions }); }) .catch(error => { @@ -60,7 +68,7 @@ const usePermissions = (params = emptyParams) => { error, }); }); - }, [getPermissions, params, setState]); + }, [getPermissions, params, setState, cacheKey]); return state; }; diff --git a/packages/ra-ui-materialui/src/button/BulkDeleteWithUndoButton.tsx b/packages/ra-ui-materialui/src/button/BulkDeleteWithUndoButton.tsx index f5d28ee8b41..d19f95e0df2 100644 --- a/packages/ra-ui-materialui/src/button/BulkDeleteWithUndoButton.tsx +++ b/packages/ra-ui-materialui/src/button/BulkDeleteWithUndoButton.tsx @@ -59,7 +59,7 @@ const BulkDeleteWithUndoButton: FC = props => { unselectAll(resource); refresh(); }, - onFailure: error => + onFailure: error => { notify( typeof error === 'string' ? error @@ -73,7 +73,9 @@ const BulkDeleteWithUndoButton: FC = props => { ? error.message : undefined, } - ), + ); + refresh(); + }, undoable: true, });