diff --git a/.changeset/green-stingrays-compete.md b/.changeset/green-stingrays-compete.md new file mode 100644 index 0000000000..4609e95c2c --- /dev/null +++ b/.changeset/green-stingrays-compete.md @@ -0,0 +1,5 @@ +--- +"@commercetools-frontend/application-shell": minor +--- + +The `ApplicationShell` and `CustomViewShell` not support an optional `enableReactStrictMode` prop to render their `children` in [Strict Mode](https://react.dev/reference/react/StrictMode). diff --git a/packages/application-shell/src/components/application-shell/application-shell.tsx b/packages/application-shell/src/components/application-shell/application-shell.tsx index 9e180664a7..056e25432e 100644 --- a/packages/application-shell/src/components/application-shell/application-shell.tsx +++ b/packages/application-shell/src/components/application-shell/application-shell.tsx @@ -1,4 +1,9 @@ -import { type ReactNode, type SyntheticEvent, useEffect } from 'react'; +import { + type ReactNode, + type SyntheticEvent, + useEffect, + StrictMode, +} from 'react'; import type { NormalizedCacheObject } from '@apollo/client'; import { ApolloClient } from '@apollo/client'; import type { TFlags } from '@flopflip/types'; @@ -41,10 +46,24 @@ type TApplicationShellProps = { onRegisterErrorListeners?: (args: { dispatch: Dispatch }) => void; onMenuItemClick?: (event: SyntheticEvent) => void; disableRoutePermissionCheck?: boolean; + enableReactStrictMode?: boolean; render?: () => JSX.Element; children?: ReactNode; }; +type TStrictModeEnablementProps = { + enableReactStrictMode?: boolean; + children?: ReactNode; +}; + +const StrictModeEnablement = (props: TStrictModeEnablementProps) => { + if (props.enableReactStrictMode) { + return {props.children}; + } else { + return <>{props.children}; + } +}; + const ApplicationShell = (props: TApplicationShellProps) => { useEffect(() => { props.onRegisterErrorListeners?.({ @@ -54,7 +73,7 @@ const ApplicationShell = (props: TApplicationShellProps) => { }, []); // <-- run only once, when component mounts return ( - <> + { return ; }} - + ); }; ApplicationShell.displayName = 'ApplicationShell'; diff --git a/packages/application-shell/src/components/custom-view-shell/custom-view-shell.tsx b/packages/application-shell/src/components/custom-view-shell/custom-view-shell.tsx index 9d2e7b0436..94f93d49d8 100644 --- a/packages/application-shell/src/components/custom-view-shell/custom-view-shell.tsx +++ b/packages/application-shell/src/components/custom-view-shell/custom-view-shell.tsx @@ -4,6 +4,7 @@ import { useRef, useState, Suspense, + StrictMode, type ReactNode, } from 'react'; import { PageUnauthorized } from '@commercetools-frontend/application-components'; @@ -45,11 +46,25 @@ type THostEventData = { type TCustomViewShellProps = { applicationMessages: TAsyncLocaleDataProps['applicationMessages']; disableDevHost?: boolean; + enableReactStrictMode?: boolean; children: ReactNode; }; const browserLocale = getBrowserLocale(window); +type TStrictModeEnablementProps = { + enableReactStrictMode?: boolean; + children?: ReactNode; +}; + +function StrictModeEnablement(props: TStrictModeEnablementProps) { + if (props.enableReactStrictMode) { + return {props.children}; + } else { + return <>{props.children}; + } +} + function CustomViewShell(props: TCustomViewShellProps) { const [hostContext, setHostContext] = useState(); const iFrameCommunicationPort = useRef(); @@ -160,19 +175,23 @@ function CustomViewShell(props: TCustomViewShellProps) { const CustomViewShellWrapper = (props: TCustomViewShellProps) => { if (process.env.NODE_ENV === 'development' && !props.disableDevHost) { return ( - }> - - - {props.children} - - - + + }> + + + {props.children} + + + + ); } return ( - - {props.children} - + + + {props.children} + + ); };