Skip to content

Commit

Permalink
Merge pull request #44544 from software-mansion-labs/fix/freeze-scree…
Browse files Browse the repository at this point in the history
…n-with-lazy-loading

[CP Staging] Add freezeScreenWithLazyLoading function

(cherry picked from commit 9d88c63)
  • Loading branch information
mountiny authored and OSBotify committed Jun 27, 2024
1 parent b03ed0a commit f58d10c
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 37 deletions.
27 changes: 5 additions & 22 deletions src/components/withPrepareCentralPaneScreen/index.native.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,10 @@
import type {ComponentType, ForwardedRef, RefAttributes} from 'react';
import React from 'react';
import getComponentDisplayName from '@libs/getComponentDisplayName';
import FreezeWrapper from '@libs/Navigation/FreezeWrapper';
import type React from 'react';
import freezeScreenWithLazyLoading from '@libs/freezeScreenWithLazyLoading';

/**
* This HOC is dependent on the platform. On native platforms, screens that aren't already displayed in the navigation stack should be frozen to prevent unnecessary rendering.
* This higher-order function is dependent on the platform. On native platforms, screens that aren't already displayed in the navigation stack should be frozen to prevent unnecessary rendering.
* It's handled this way only on mobile platforms because on the web, more than one screen is displayed in a wide layout, so these screens shouldn't be frozen.
*/
export default function withPrepareCentralPaneScreen<TProps, TRef>(
WrappedComponent: ComponentType<TProps & RefAttributes<TRef>>,
): (props: TProps & React.RefAttributes<TRef>) => React.ReactElement | null {
function WithPrepareCentralPaneScreen(props: TProps, ref: ForwardedRef<TRef>) {
return (
<FreezeWrapper>
<WrappedComponent
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
ref={ref}
/>
</FreezeWrapper>
);
}

WithPrepareCentralPaneScreen.displayName = `WithPrepareCentralPaneScreen(${getComponentDisplayName(WrappedComponent)})`;
return React.forwardRef(WithPrepareCentralPaneScreen);
export default function withPrepareCentralPaneScreen(lazyComponent: () => React.ComponentType) {
return freezeScreenWithLazyLoading(lazyComponent);
}
8 changes: 4 additions & 4 deletions src/components/withPrepareCentralPaneScreen/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type {ComponentType} from 'react';
import type React from 'react';

/**
* This HOC is dependent on the platform. On native platforms, screens that aren't already displayed in the navigation stack should be frozen to prevent unnecessary rendering.
* This higher-order function is dependent on the platform. On native platforms, screens that aren't already displayed in the navigation stack should be frozen to prevent unnecessary rendering.
* It's handled this way only on mobile platforms because on the web, more than one screen is displayed in a wide layout, so these screens shouldn't be frozen.
*/
export default function withPrepareCentralPaneScreen(WrappedComponent: ComponentType) {
return WrappedComponent;
export default function withPrepareCentralPaneScreen(lazyComponent: () => React.ComponentType) {
return lazyComponent;
}
22 changes: 11 additions & 11 deletions src/libs/Navigation/AppNavigator/CENTRAL_PANE_SCREENS.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ import type ReactComponentModule from '@src/types/utils/ReactComponentModule';
type Screens = Partial<Record<CentralPaneName, () => React.ComponentType>>;

const CENTRAL_PANE_SCREENS = {
[SCREENS.SETTINGS.WORKSPACES]: () => withPrepareCentralPaneScreen(require<ReactComponentModule>('../../../pages/workspace/WorkspacesListPage').default),
[SCREENS.SETTINGS.PREFERENCES.ROOT]: () => withPrepareCentralPaneScreen(require<ReactComponentModule>('../../../pages/settings/Preferences/PreferencesPage').default),
[SCREENS.SETTINGS.SECURITY]: () => withPrepareCentralPaneScreen(require<ReactComponentModule>('../../../pages/settings/Security/SecuritySettingsPage').default),
[SCREENS.SETTINGS.PROFILE.ROOT]: () => withPrepareCentralPaneScreen(require<ReactComponentModule>('../../../pages/settings/Profile/ProfilePage').default),
[SCREENS.SETTINGS.WALLET.ROOT]: () => withPrepareCentralPaneScreen(require<ReactComponentModule>('../../../pages/settings/Wallet/WalletPage').default),
[SCREENS.SETTINGS.ABOUT]: () => withPrepareCentralPaneScreen(require<ReactComponentModule>('../../../pages/settings/AboutPage/AboutPage').default),
[SCREENS.SETTINGS.TROUBLESHOOT]: () => withPrepareCentralPaneScreen(require<ReactComponentModule>('../../../pages/settings/Troubleshoot/TroubleshootPage').default),
[SCREENS.SETTINGS.SAVE_THE_WORLD]: () => withPrepareCentralPaneScreen(require<ReactComponentModule>('../../../pages/TeachersUnite/SaveTheWorldPage').default),
[SCREENS.SETTINGS.SUBSCRIPTION.ROOT]: () => withPrepareCentralPaneScreen(require<ReactComponentModule>('../../../pages/settings/Subscription/SubscriptionSettingsPage').default),
[SCREENS.SEARCH.CENTRAL_PANE]: () => withPrepareCentralPaneScreen(require<ReactComponentModule>('../../../pages/Search/SearchPage').default),
[SCREENS.REPORT]: () => withPrepareCentralPaneScreen(require<ReactComponentModule>('./ReportScreenWrapper').default),
[SCREENS.SETTINGS.WORKSPACES]: withPrepareCentralPaneScreen(() => require<ReactComponentModule>('../../../pages/workspace/WorkspacesListPage').default),
[SCREENS.SETTINGS.PREFERENCES.ROOT]: withPrepareCentralPaneScreen(() => require<ReactComponentModule>('../../../pages/settings/Preferences/PreferencesPage').default),
[SCREENS.SETTINGS.SECURITY]: withPrepareCentralPaneScreen(() => require<ReactComponentModule>('../../../pages/settings/Security/SecuritySettingsPage').default),
[SCREENS.SETTINGS.PROFILE.ROOT]: withPrepareCentralPaneScreen(() => require<ReactComponentModule>('../../../pages/settings/Profile/ProfilePage').default),
[SCREENS.SETTINGS.WALLET.ROOT]: withPrepareCentralPaneScreen(() => require<ReactComponentModule>('../../../pages/settings/Wallet/WalletPage').default),
[SCREENS.SETTINGS.ABOUT]: withPrepareCentralPaneScreen(() => require<ReactComponentModule>('../../../pages/settings/AboutPage/AboutPage').default),
[SCREENS.SETTINGS.TROUBLESHOOT]: withPrepareCentralPaneScreen(() => require<ReactComponentModule>('../../../pages/settings/Troubleshoot/TroubleshootPage').default),
[SCREENS.SETTINGS.SAVE_THE_WORLD]: withPrepareCentralPaneScreen(() => require<ReactComponentModule>('../../../pages/TeachersUnite/SaveTheWorldPage').default),
[SCREENS.SETTINGS.SUBSCRIPTION.ROOT]: withPrepareCentralPaneScreen(() => require<ReactComponentModule>('../../../pages/settings/Subscription/SubscriptionSettingsPage').default),
[SCREENS.SEARCH.CENTRAL_PANE]: withPrepareCentralPaneScreen(() => require<ReactComponentModule>('../../../pages/Search/SearchPage').default),
[SCREENS.REPORT]: withPrepareCentralPaneScreen(() => require<ReactComponentModule>('./ReportScreenWrapper').default),
} satisfies Screens;

export default CENTRAL_PANE_SCREENS;
20 changes: 20 additions & 0 deletions src/libs/freezeScreenWithLazyLoading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import FreezeWrapper from './Navigation/FreezeWrapper';

function FrozenScreen<TProps extends React.JSX.IntrinsicAttributes>(WrappedComponent: React.ComponentType<TProps>) {
return (props: TProps) => (
<FreezeWrapper>
<WrappedComponent
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
/>
</FreezeWrapper>
);
}

export default function freezeScreenWithLazyLoading(lazyComponent: () => React.ComponentType) {
return () => {
const Component = lazyComponent();
return FrozenScreen(Component);
};
}

0 comments on commit f58d10c

Please sign in to comment.