diff --git a/packages/ra-core/src/auth/WithPermissions.tsx b/packages/ra-core/src/auth/WithPermissions.tsx
index 674c0286f2e..a19cb38f6d6 100644
--- a/packages/ra-core/src/auth/WithPermissions.tsx
+++ b/packages/ra-core/src/auth/WithPermissions.tsx
@@ -3,7 +3,7 @@ import { Location } from 'react-router-dom';
import warning from '../util/warning';
import { useAuthenticated } from './useAuthenticated';
-import usePermissionsOptimized from './usePermissionsOptimized';
+import usePermissions from './usePermissions';
export interface WithPermissionsChildrenParams {
permissions: any;
@@ -76,7 +76,7 @@ const WithPermissions = (props: WithPermissionsProps) => {
);
useAuthenticated(authParams);
- const { permissions } = usePermissionsOptimized(authParams);
+ const { permissions } = usePermissions(authParams);
// render even though the usePermissions() call isn't finished (optimistic rendering)
if (component) {
return createElement(component, { permissions, ...rest });
diff --git a/packages/ra-core/src/auth/usePermissionsOptimized.spec.tsx b/packages/ra-core/src/auth/usePermissionsOptimized.spec.tsx
deleted file mode 100644
index ef38304c53c..00000000000
--- a/packages/ra-core/src/auth/usePermissionsOptimized.spec.tsx
+++ /dev/null
@@ -1,111 +0,0 @@
-import * as React from 'react';
-import { render, act, cleanup } from '@testing-library/react';
-import expect from 'expect';
-import usePermissionsOptimized from './usePermissionsOptimized';
-import AuthContext from './AuthContext';
-
-describe('usePermissionsOptimized', () => {
- afterEach(cleanup);
-
- const CallPermissionsOnMount = ({ number, authParams }: any) => {
- const { permissions } = usePermissionsOptimized(authParams);
- return (
-
- permissions {number}: {permissions}
-
- );
- };
-
- it('returns undefined on mount', () => {
- const getPermissions = jest.fn(() => Promise.resolve('admin'));
- const { queryByText } = render(
-
-
-
-
-
- );
- expect(queryByText('permissions :')).not.toBeNull();
- expect(queryByText('permissions : admin')).toBeNull();
- });
-
- it('returns permissions from authProvider after resolve', async () => {
- const getPermissions = jest.fn(() => Promise.resolve('admin'));
- const { queryByText } = render(
-
-
-
-
-
- );
- await act(async () => await new Promise(r => setTimeout(r)));
- expect(queryByText('permissions :')).toBeNull();
- expect(queryByText('permissions : admin')).not.toBeNull();
- });
-
- it('does not rerender once the permissions have already been fetched', async () => {
- let renders = 0;
- const ComponentToTest = () => {
- const { permissions } = usePermissionsOptimized({ test: 3 });
- renders++;
- return {permissions}
;
- };
- const getPermissions = jest.fn(() => Promise.resolve('admin'));
-
- // first usage
- const { queryByText } = render(
-
-
-
- );
- expect(renders).toBe(1); // renders on mount
- expect(getPermissions).toBeCalledTimes(1);
- expect(queryByText('admin')).toBeNull();
- await act(async () => await new Promise(r => setTimeout(r)));
- expect(renders).toBe(2); // re-renders when the getPermissions returns
- expect(queryByText('admin')).not.toBeNull();
-
- // second usage
- cleanup();
- renders = 0;
- const { queryByText: queryByText2 } = render(
-
-
-
- );
- expect(renders).toBe(1); // renders on mount
- expect(getPermissions).toBeCalledTimes(2);
- expect(queryByText2('admin')).not.toBeNull(); // answer from the cache
- await act(async () => await new Promise(r => setTimeout(r)));
- expect(renders).toBe(1); // does not rerender when the getPermissions returns the same permissions
- });
-
- it('can be called by two independent components', async () => {
- const getPermissions = jest.fn(() => Promise.resolve('admin'));
- const { queryByText } = render(
-
-
-
-
-
-
- );
- expect(queryByText('permissions 1:')).not.toBeNull();
- expect(queryByText('permissions 2:')).not.toBeNull();
- expect(queryByText('permissions 1: admin')).toBeNull();
- expect(queryByText('permissions 2: admin')).toBeNull();
- expect(getPermissions).toBeCalledTimes(2);
- await act(async () => await new Promise(r => setTimeout(r)));
- expect(queryByText('permissions 1:')).toBeNull();
- expect(queryByText('permissions 2:')).toBeNull();
- expect(queryByText('permissions 1: admin')).not.toBeNull();
- expect(queryByText('permissions 2: admin')).not.toBeNull();
- expect(getPermissions).toBeCalledTimes(2);
- });
-});
diff --git a/packages/ra-core/src/auth/usePermissionsOptimized.ts b/packages/ra-core/src/auth/usePermissionsOptimized.ts
index 74681e2ddbd..fe932d94c00 100644
--- a/packages/ra-core/src/auth/usePermissionsOptimized.ts
+++ b/packages/ra-core/src/auth/usePermissionsOptimized.ts
@@ -1,79 +1,14 @@
-import { useEffect } from 'react';
-import isEqual from 'lodash/isEqual';
-
-import useGetPermissions from './useGetPermissions';
-import { useSafeSetState } from '../util/hooks';
-
-interface State {
- permissions?: any;
- error?: any;
-}
+import usePermissions from './usePermissions';
const emptyParams = {};
-// keep a cache of already fetched permissions to initialize state for new
-// components and avoid a useless rerender if the permissions haven't changed
-const alreadyFetchedPermissions = { '{}': undefined };
-
/**
- * Hook for getting user permissions without the loading state.
- *
- * When compared to usePermissions, this hook doesn't cause a re-render
- * when the permissions haven't changed since the last call.
- *
- * This hook doesn't handle the loading state.
+ * @deprecated use usePermissions instead
*
* @see usePermissions
- *
- * Calls the authProvider.getPermissions() method asynchronously.
- * If the authProvider returns a rejected promise, returns empty permissions.
- *
- * The return value updates according to the request state:
- *
- * - start: { permissions: [previously fetched permissions for these params] }
- * - success: { permissions: [permissions returned by the authProvider (usually the same as on start)] }
- * - error: { error: [error from provider] }
- *
- * Useful to enable features based on user permissions
- *
- * @param {Object} params Any params you want to pass to the authProvider
- *
- * @returns The current auth check state. Destructure as { permissions, error }.
- *
- * @example
- * import { usePermissionsOptimized } from 'react-admin';
- *
- * const PostDetail = props => {
- * const { permissions } = usePermissionsOptimized();
- * if (permissions !== 'editor') {
- * return
- * } else {
- * return
- * }
- * };
*/
const usePermissionsOptimized = (params = emptyParams) => {
- const key = JSON.stringify(params);
- const [state, setState] = useSafeSetState({
- permissions: alreadyFetchedPermissions[key],
- });
- const getPermissions = useGetPermissions();
- useEffect(() => {
- getPermissions(params)
- .then(permissions => {
- if (!isEqual(permissions, state.permissions)) {
- alreadyFetchedPermissions[key] = permissions;
- setState({ permissions });
- }
- })
- .catch(error => {
- setState({
- error,
- });
- });
- }, [getPermissions, key]); // eslint-disable-line react-hooks/exhaustive-deps
-
- return state;
+ return usePermissions(params);
};
export default usePermissionsOptimized;