diff --git a/packages/ra-core/src/controller/edit/useEditController.ts b/packages/ra-core/src/controller/edit/useEditController.ts index 3ed29befbbc..9ceeff979cd 100644 --- a/packages/ra-core/src/controller/edit/useEditController.ts +++ b/packages/ra-core/src/controller/edit/useEditController.ts @@ -3,7 +3,11 @@ import { useParams } from 'react-router-dom'; import { useAuthenticated, useRequireAccess } from '../../auth'; import { RaRecord, MutationMode, TransformData } from '../../types'; -import { useRedirect, RedirectionSideEffect } from '../../routing'; +import { + useRedirect, + RedirectionSideEffect, + useCreatePath, +} from '../../routing'; import { useNotify } from '../../notification'; import { useGetOne, @@ -82,6 +86,7 @@ export const useEditController = < const getRecordRepresentation = useGetRecordRepresentation(resource); const translate = useTranslate(); const notify = useNotify(); + const createPath = useCreatePath(); const redirect = useRedirect(); const refresh = useRefresh(); const { id: routeId } = useParams<'id'>(); @@ -121,7 +126,15 @@ export const useEditController = < notify('ra.notification.item_doesnt_exist', { type: 'error', }); - redirect('list', resource); + // We need to flushSync to ensure the redirect happens before the refresh + // Otherwise this can cause an infinite loop when the record is not found + redirect(() => ({ + pathname: createPath({ + resource, + type: 'list', + }), + flushSync: true, + })); refresh(); }, refetchOnReconnect: false, diff --git a/packages/ra-core/src/controller/show/useShowController.ts b/packages/ra-core/src/controller/show/useShowController.ts index 0138090e6da..a0ef822f2f1 100644 --- a/packages/ra-core/src/controller/show/useShowController.ts +++ b/packages/ra-core/src/controller/show/useShowController.ts @@ -9,7 +9,7 @@ import { UseGetOneOptions, } from '../../dataProvider'; import { useTranslate } from '../../i18n'; -import { useRedirect } from '../../routing'; +import { useCreatePath, useRedirect } from '../../routing'; import { useNotify } from '../../notification'; import { useResourceContext, @@ -80,6 +80,7 @@ export const useShowController = < const getRecordRepresentation = useGetRecordRepresentation(resource); const translate = useTranslate(); const notify = useNotify(); + const createPath = useCreatePath(); const redirect = useRedirect(); const refresh = useRefresh(); const { id: routeId } = useParams<'id'>(); @@ -109,7 +110,16 @@ export const useShowController = < notify('ra.notification.item_doesnt_exist', { type: 'error', }); - redirect('list', resource); + + // We need to flushSync to ensure the redirect happens before the refresh + // Otherwise this can cause an infinite loop when the record is not found + redirect(() => ({ + pathname: createPath({ + resource, + type: 'list', + }), + flushSync: true, + })); refresh(); }, retry: false,