From c6f1325ea0503cbbebfa08a44eaabd545045409b Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Mon, 2 Mar 2026 14:58:30 +0100 Subject: [PATCH 1/6] prevent remounting LHN after navigating away from Inbox --- .../useCustomRootStackNavigatorState/index.ts | 12 +++--------- .../AppNavigator/usePreloadFullScreenNavigators.ts | 8 ++++++++ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/createRootStackNavigator/useCustomRootStackNavigatorState/index.ts b/src/libs/Navigation/AppNavigator/createRootStackNavigator/useCustomRootStackNavigatorState/index.ts index 88a7135aa0b3..4f09f87a22e0 100644 --- a/src/libs/Navigation/AppNavigator/createRootStackNavigator/useCustomRootStackNavigatorState/index.ts +++ b/src/libs/Navigation/AppNavigator/createRootStackNavigator/useCustomRootStackNavigatorState/index.ts @@ -2,17 +2,11 @@ import {isFullScreenName} from '@libs/Navigation/helpers/isNavigatorName'; import type {CustomStateHookProps} from '@libs/Navigation/PlatformStackNavigation/types'; // This is an optimization to keep mounted only last few screens in the stack. +// We keep the last full screen and the one before it to avoid unmounting persistent screens +// (like ReportsSplitNavigator) which contain heavy component trees (e.g. LHN with thousands of items). export default function useCustomRootStackNavigatorState({state}: CustomStateHookProps) { const lastSplitIndex = state.routes.findLastIndex((route) => isFullScreenName(route.name)); - let indexToSlice = Math.max(0, lastSplitIndex); - const hasPrevRoute = lastSplitIndex > 0; - const isPrevFullScreen = isFullScreenName(state.routes.at(lastSplitIndex - 1)?.name); - - // If the route before the last full screen is e.g. RHP, we should leave it in the rendered routes, - // as there may be display issues (blank screen) when navigating back and recreating that route to render. - if (hasPrevRoute && !isPrevFullScreen) { - indexToSlice = lastSplitIndex - 1; - } + const indexToSlice = Math.max(0, lastSplitIndex - 1); const routesToRender = state.routes.slice(indexToSlice, state.routes.length); return {...state, routes: routesToRender, index: routesToRender.length - 1}; } diff --git a/src/libs/Navigation/AppNavigator/usePreloadFullScreenNavigators.ts b/src/libs/Navigation/AppNavigator/usePreloadFullScreenNavigators.ts index 8c1adcde02e7..74a857bd3596 100644 --- a/src/libs/Navigation/AppNavigator/usePreloadFullScreenNavigators.ts +++ b/src/libs/Navigation/AppNavigator/usePreloadFullScreenNavigators.ts @@ -147,6 +147,14 @@ function usePreloadFullScreenNavigators() { continue; } + // Don't preload tabs whose navigator is already in the regular routes stack + const currentRoutes = navigation.getState().routes; + const isRouteInStack = currentRoutes.some((r) => TAB_TO_FULLSCREEN[tabName].includes(r.name as FullScreenName)); + + if (isRouteInStack) { + continue; + } + // Preload everything else preloadTab(tabName, navigation, subscriptionPlan); } From f8a01ee574b5cb1c5835520955bd5e23f6edc863 Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Tue, 3 Mar 2026 08:04:56 +0100 Subject: [PATCH 2/6] move navigation.getState().routes outside the loop --- .../Navigation/AppNavigator/usePreloadFullScreenNavigators.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/usePreloadFullScreenNavigators.ts b/src/libs/Navigation/AppNavigator/usePreloadFullScreenNavigators.ts index 74a857bd3596..ca424767b0ca 100644 --- a/src/libs/Navigation/AppNavigator/usePreloadFullScreenNavigators.ts +++ b/src/libs/Navigation/AppNavigator/usePreloadFullScreenNavigators.ts @@ -134,6 +134,7 @@ function usePreloadFullScreenNavigators() { } hasPreloadedRef.current = true; setTimeout(() => { + const currentRoutes = navigation.getState().routes; for (const tabName of TABS_TO_PRELOAD) { // Don't preload the current tab const isCurrentTab = TAB_TO_FULLSCREEN[tabName].includes(route.name as FullScreenName); @@ -148,9 +149,8 @@ function usePreloadFullScreenNavigators() { } // Don't preload tabs whose navigator is already in the regular routes stack - const currentRoutes = navigation.getState().routes; const isRouteInStack = currentRoutes.some((r) => TAB_TO_FULLSCREEN[tabName].includes(r.name as FullScreenName)); - + if (isRouteInStack) { continue; } From 7664d463137745dd9b26c0d333d3563f49cd1e35 Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Tue, 3 Mar 2026 11:50:08 +0100 Subject: [PATCH 3/6] keep preserved screens active on web --- Mobile-Expensify | 2 +- .../Navigation/NavigationTabBar/index.tsx | 33 +++---------------- .../GetStateForActionHandlers.ts | 8 +++++ .../useCustomRootStackNavigatorState/index.ts | 21 ++++++++++-- .../index.tsx | 3 +- .../types/NavigatorComponent.ts | 1 + 6 files changed, 35 insertions(+), 33 deletions(-) diff --git a/Mobile-Expensify b/Mobile-Expensify index b2bae8ae34b2..b795e6a8e011 160000 --- a/Mobile-Expensify +++ b/Mobile-Expensify @@ -1 +1 @@ -Subproject commit b2bae8ae34b2c4169bd741d4ea9d68083f650afa +Subproject commit b795e6a8e011c1bc3bca951784b7d85d92acbfa0 diff --git a/src/components/Navigation/NavigationTabBar/index.tsx b/src/components/Navigation/NavigationTabBar/index.tsx index e3c3ccd805ac..3f4958005fe3 100644 --- a/src/components/Navigation/NavigationTabBar/index.tsx +++ b/src/components/Navigation/NavigationTabBar/index.tsx @@ -1,7 +1,6 @@ import {StackActions} from '@react-navigation/native'; import React from 'react'; import {View} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import FloatingCameraButton from '@components/FloatingCameraButton'; import FloatingGPSButton from '@components/FloatingGPSButton'; @@ -13,7 +12,6 @@ import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useReportAttributes from '@hooks/useReportAttributes'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; -import useRootNavigationState from '@hooks/useRootNavigationState'; import {useSidebarOrderedReportsState} from '@hooks/useSidebarOrderedReports'; import useStyleUtils from '@hooks/useStyleUtils'; import useSubscriptionPlan from '@hooks/useSubscriptionPlan'; @@ -26,16 +24,12 @@ import Navigation from '@libs/Navigation/Navigation'; import {startSpan} from '@libs/telemetry/activeSpans'; import {getChatTabBrickRoad} from '@libs/WorkspacesSettingsUtils'; import navigationRef from '@navigation/navigationRef'; -import type {ReportsSplitNavigatorParamList} from '@navigation/types'; import NavigationTabBarAvatar from '@pages/inbox/sidebar/NavigationTabBarAvatar'; import NavigationTabBarFloatingActionButton from '@pages/inbox/sidebar/NavigationTabBarFloatingActionButton'; import CONST from '@src/CONST'; import NAVIGATORS from '@src/NAVIGATORS'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import SCREENS from '@src/SCREENS'; -import type {Report} from '@src/types/onyx'; -import getLastRoute from './getLastRoute'; import NAVIGATION_TABS from './NAVIGATION_TABS'; import SearchTabButton from './SearchTabButton'; import TabBarItem from './TabBarItem'; @@ -47,10 +41,6 @@ type NavigationTabBarProps = { shouldShowFloatingButtons?: boolean; }; -function doesLastReportExistSelector(report: OnyxEntry) { - return !!report?.reportID; -} - function NavigationTabBar({selectedTab, isTopLevelBar = false, shouldShowFloatingButtons = true}: NavigationTabBarProps) { const theme = useTheme(); const styles = useThemeStyles(); @@ -60,15 +50,6 @@ function NavigationTabBar({selectedTab, isTopLevelBar = false, shouldShowFloatin const subscriptionPlan = useSubscriptionPlan(); const expensifyIcons = useMemoizedLazyExpensifyIcons(['ExpensifyAppIcon', 'Home', 'Inbox']); - const lastReportRoute = useRootNavigationState((rootState) => { - if (!rootState) { - return undefined; - } - return getLastRoute(rootState, NAVIGATORS.REPORTS_SPLIT_NAVIGATOR, SCREENS.REPORT); - }); - const lastReportRouteReportID = (lastReportRoute?.params as ReportsSplitNavigatorParamList[typeof SCREENS.REPORT])?.reportID; - const [doesLastReportExist] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${lastReportRouteReportID}`, {selector: doesLastReportExistSelector}, [lastReportRouteReportID]); - const reportAttributes = useReportAttributes(); const {shouldUseNarrowLayout} = useResponsiveLayout(); const chatTabBrickRoad = getChatTabBrickRoad(orderedReportIDs, reportAttributes); @@ -104,16 +85,10 @@ function NavigationTabBar({selectedTab, isTopLevelBar = false, shouldShowFloatin }); if (!shouldUseNarrowLayout) { - if (doesLastReportExist && lastReportRoute) { - const {reportID, reportActionID, referrer, backTo} = lastReportRoute.params as ReportsSplitNavigatorParamList[typeof SCREENS.REPORT]; - Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(reportID, reportActionID, referrer, backTo)); - return; - } - - if (isRoutePreloaded(NAVIGATORS.REPORTS_SPLIT_NAVIGATOR)) { - navigationRef.dispatch(StackActions.push(NAVIGATORS.REPORTS_SPLIT_NAVIGATOR)); - return; - } + // Push triggers the router-level pop-back if REPORTS_SPLIT already exists in the stack. + // This preserves the inner state (last viewed report) without creating a new ReportScreen instance. + navigationRef.dispatch(StackActions.push(NAVIGATORS.REPORTS_SPLIT_NAVIGATOR)); + return; } Navigation.navigate(ROUTES.INBOX); diff --git a/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts b/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts index b9a8ad120b0c..4700ba4b4afd 100644 --- a/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts +++ b/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts @@ -123,6 +123,14 @@ function handlePushFullscreenAction( const targetScreen = action.payload?.params && 'screen' in action.payload.params ? (action.payload?.params?.screen as string) : undefined; const navigatorName = action.payload.name; + // If the target navigator already exists in the stack, pop back to it instead of pushing + // a duplicate. This preserves the route key and avoids remounting heavy component trees. + const existingIndex = state.routes.findLastIndex((route) => route.name === navigatorName); + if (existingIndex !== -1 && existingIndex !== state.routes.length - 1) { + const popAction = StackActions.pop(state.routes.length - 1 - existingIndex); + return stackRouter.getStateForAction(state, popAction, configOptions); + } + // If we navigate to the central screen of the split navigator, we need to filter this navigator from preloadedRoutes to remove a sidebar screen from the state const shouldFilterPreloadedRoutes = getIsNarrowLayout() && diff --git a/src/libs/Navigation/AppNavigator/createRootStackNavigator/useCustomRootStackNavigatorState/index.ts b/src/libs/Navigation/AppNavigator/createRootStackNavigator/useCustomRootStackNavigatorState/index.ts index 4f09f87a22e0..62d079ec075c 100644 --- a/src/libs/Navigation/AppNavigator/createRootStackNavigator/useCustomRootStackNavigatorState/index.ts +++ b/src/libs/Navigation/AppNavigator/createRootStackNavigator/useCustomRootStackNavigatorState/index.ts @@ -4,9 +4,26 @@ import type {CustomStateHookProps} from '@libs/Navigation/PlatformStackNavigatio // This is an optimization to keep mounted only last few screens in the stack. // We keep the last full screen and the one before it to avoid unmounting persistent screens // (like ReportsSplitNavigator) which contain heavy component trees (e.g. LHN with thousands of items). -export default function useCustomRootStackNavigatorState({state}: CustomStateHookProps) { +export default function useCustomRootStackNavigatorState({state, persistentScreens}: CustomStateHookProps) { const lastSplitIndex = state.routes.findLastIndex((route) => isFullScreenName(route.name)); const indexToSlice = Math.max(0, lastSplitIndex - 1); - const routesToRender = state.routes.slice(indexToSlice, state.routes.length); + + if (indexToSlice === 0) { + return {...state, routes: state.routes, index: state.routes.length - 1}; + } + + // Collect persistent routes that fell outside the slice window + const persistentScreensSet = persistentScreens ? new Set(persistentScreens) : undefined; + const persistentRoutesBefore = []; + for (let i = 0; i < indexToSlice; i++) { + const route = state.routes.at(i); + if (route && persistentScreensSet?.has(route.name)) { + persistentRoutesBefore.push(route); + } + } + + const slicedRoutes = state.routes.slice(indexToSlice); + const routesToRender = persistentRoutesBefore.length > 0 ? [...persistentRoutesBefore, ...slicedRoutes] : slicedRoutes; + return {...state, routes: routesToRender, index: routesToRender.length - 1}; } diff --git a/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.tsx b/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.tsx index 730e269d507a..4a7fc98d8f33 100644 --- a/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.tsx +++ b/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.tsx @@ -73,8 +73,9 @@ function createPlatformStackNavigatorComponent; displayName: string; parentRoute?: RouteProp; + persistentScreens?: string[]; }; // Props for the custom state hook. From a09a9febdf9b5bf65f971c25a9e83f97ed0c03d3 Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Tue, 3 Mar 2026 12:17:26 +0100 Subject: [PATCH 4/6] Prevent pop-back to bottom of navigation stack --- .../createRootStackNavigator/GetStateForActionHandlers.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts b/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts index 4700ba4b4afd..7bfae5778879 100644 --- a/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts +++ b/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts @@ -125,8 +125,9 @@ function handlePushFullscreenAction( // If the target navigator already exists in the stack, pop back to it instead of pushing // a duplicate. This preserves the route key and avoids remounting heavy component trees. + // Never pop to the very first route (index 0) as that would destroy all navigators above it. const existingIndex = state.routes.findLastIndex((route) => route.name === navigatorName); - if (existingIndex !== -1 && existingIndex !== state.routes.length - 1) { + if (existingIndex > 0 && existingIndex !== state.routes.length - 1) { const popAction = StackActions.pop(state.routes.length - 1 - existingIndex); return stackRouter.getStateForAction(state, popAction, configOptions); } From 4512c8a52af55a26a928cdce74e41f01909b7b4b Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Tue, 3 Mar 2026 14:31:26 +0100 Subject: [PATCH 5/6] Revert "Prevent pop-back to bottom of navigation stack" This reverts commit a09a9febdf9b5bf65f971c25a9e83f97ed0c03d3. --- .../createRootStackNavigator/GetStateForActionHandlers.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts b/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts index 7bfae5778879..4700ba4b4afd 100644 --- a/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts +++ b/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts @@ -125,9 +125,8 @@ function handlePushFullscreenAction( // If the target navigator already exists in the stack, pop back to it instead of pushing // a duplicate. This preserves the route key and avoids remounting heavy component trees. - // Never pop to the very first route (index 0) as that would destroy all navigators above it. const existingIndex = state.routes.findLastIndex((route) => route.name === navigatorName); - if (existingIndex > 0 && existingIndex !== state.routes.length - 1) { + if (existingIndex !== -1 && existingIndex !== state.routes.length - 1) { const popAction = StackActions.pop(state.routes.length - 1 - existingIndex); return stackRouter.getStateForAction(state, popAction, configOptions); } From a699d01ccb225cf7a447f01b049f969fbb61961e Mon Sep 17 00:00:00 2001 From: Tomasz Misiukiewicz Date: Tue, 3 Mar 2026 14:31:33 +0100 Subject: [PATCH 6/6] Revert "keep preserved screens active on web" This reverts commit 7664d463137745dd9b26c0d333d3563f49cd1e35. --- .../Navigation/NavigationTabBar/index.tsx | 33 ++++++++++++++++--- .../GetStateForActionHandlers.ts | 8 ----- .../useCustomRootStackNavigatorState/index.ts | 21 ++---------- .../index.tsx | 3 +- .../types/NavigatorComponent.ts | 1 - 5 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/components/Navigation/NavigationTabBar/index.tsx b/src/components/Navigation/NavigationTabBar/index.tsx index 3f4958005fe3..e3c3ccd805ac 100644 --- a/src/components/Navigation/NavigationTabBar/index.tsx +++ b/src/components/Navigation/NavigationTabBar/index.tsx @@ -1,6 +1,7 @@ import {StackActions} from '@react-navigation/native'; import React from 'react'; import {View} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import FloatingCameraButton from '@components/FloatingCameraButton'; import FloatingGPSButton from '@components/FloatingGPSButton'; @@ -12,6 +13,7 @@ import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useReportAttributes from '@hooks/useReportAttributes'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; +import useRootNavigationState from '@hooks/useRootNavigationState'; import {useSidebarOrderedReportsState} from '@hooks/useSidebarOrderedReports'; import useStyleUtils from '@hooks/useStyleUtils'; import useSubscriptionPlan from '@hooks/useSubscriptionPlan'; @@ -24,12 +26,16 @@ import Navigation from '@libs/Navigation/Navigation'; import {startSpan} from '@libs/telemetry/activeSpans'; import {getChatTabBrickRoad} from '@libs/WorkspacesSettingsUtils'; import navigationRef from '@navigation/navigationRef'; +import type {ReportsSplitNavigatorParamList} from '@navigation/types'; import NavigationTabBarAvatar from '@pages/inbox/sidebar/NavigationTabBarAvatar'; import NavigationTabBarFloatingActionButton from '@pages/inbox/sidebar/NavigationTabBarFloatingActionButton'; import CONST from '@src/CONST'; import NAVIGATORS from '@src/NAVIGATORS'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import SCREENS from '@src/SCREENS'; +import type {Report} from '@src/types/onyx'; +import getLastRoute from './getLastRoute'; import NAVIGATION_TABS from './NAVIGATION_TABS'; import SearchTabButton from './SearchTabButton'; import TabBarItem from './TabBarItem'; @@ -41,6 +47,10 @@ type NavigationTabBarProps = { shouldShowFloatingButtons?: boolean; }; +function doesLastReportExistSelector(report: OnyxEntry) { + return !!report?.reportID; +} + function NavigationTabBar({selectedTab, isTopLevelBar = false, shouldShowFloatingButtons = true}: NavigationTabBarProps) { const theme = useTheme(); const styles = useThemeStyles(); @@ -50,6 +60,15 @@ function NavigationTabBar({selectedTab, isTopLevelBar = false, shouldShowFloatin const subscriptionPlan = useSubscriptionPlan(); const expensifyIcons = useMemoizedLazyExpensifyIcons(['ExpensifyAppIcon', 'Home', 'Inbox']); + const lastReportRoute = useRootNavigationState((rootState) => { + if (!rootState) { + return undefined; + } + return getLastRoute(rootState, NAVIGATORS.REPORTS_SPLIT_NAVIGATOR, SCREENS.REPORT); + }); + const lastReportRouteReportID = (lastReportRoute?.params as ReportsSplitNavigatorParamList[typeof SCREENS.REPORT])?.reportID; + const [doesLastReportExist] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${lastReportRouteReportID}`, {selector: doesLastReportExistSelector}, [lastReportRouteReportID]); + const reportAttributes = useReportAttributes(); const {shouldUseNarrowLayout} = useResponsiveLayout(); const chatTabBrickRoad = getChatTabBrickRoad(orderedReportIDs, reportAttributes); @@ -85,10 +104,16 @@ function NavigationTabBar({selectedTab, isTopLevelBar = false, shouldShowFloatin }); if (!shouldUseNarrowLayout) { - // Push triggers the router-level pop-back if REPORTS_SPLIT already exists in the stack. - // This preserves the inner state (last viewed report) without creating a new ReportScreen instance. - navigationRef.dispatch(StackActions.push(NAVIGATORS.REPORTS_SPLIT_NAVIGATOR)); - return; + if (doesLastReportExist && lastReportRoute) { + const {reportID, reportActionID, referrer, backTo} = lastReportRoute.params as ReportsSplitNavigatorParamList[typeof SCREENS.REPORT]; + Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(reportID, reportActionID, referrer, backTo)); + return; + } + + if (isRoutePreloaded(NAVIGATORS.REPORTS_SPLIT_NAVIGATOR)) { + navigationRef.dispatch(StackActions.push(NAVIGATORS.REPORTS_SPLIT_NAVIGATOR)); + return; + } } Navigation.navigate(ROUTES.INBOX); diff --git a/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts b/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts index 4700ba4b4afd..b9a8ad120b0c 100644 --- a/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts +++ b/src/libs/Navigation/AppNavigator/createRootStackNavigator/GetStateForActionHandlers.ts @@ -123,14 +123,6 @@ function handlePushFullscreenAction( const targetScreen = action.payload?.params && 'screen' in action.payload.params ? (action.payload?.params?.screen as string) : undefined; const navigatorName = action.payload.name; - // If the target navigator already exists in the stack, pop back to it instead of pushing - // a duplicate. This preserves the route key and avoids remounting heavy component trees. - const existingIndex = state.routes.findLastIndex((route) => route.name === navigatorName); - if (existingIndex !== -1 && existingIndex !== state.routes.length - 1) { - const popAction = StackActions.pop(state.routes.length - 1 - existingIndex); - return stackRouter.getStateForAction(state, popAction, configOptions); - } - // If we navigate to the central screen of the split navigator, we need to filter this navigator from preloadedRoutes to remove a sidebar screen from the state const shouldFilterPreloadedRoutes = getIsNarrowLayout() && diff --git a/src/libs/Navigation/AppNavigator/createRootStackNavigator/useCustomRootStackNavigatorState/index.ts b/src/libs/Navigation/AppNavigator/createRootStackNavigator/useCustomRootStackNavigatorState/index.ts index 62d079ec075c..4f09f87a22e0 100644 --- a/src/libs/Navigation/AppNavigator/createRootStackNavigator/useCustomRootStackNavigatorState/index.ts +++ b/src/libs/Navigation/AppNavigator/createRootStackNavigator/useCustomRootStackNavigatorState/index.ts @@ -4,26 +4,9 @@ import type {CustomStateHookProps} from '@libs/Navigation/PlatformStackNavigatio // This is an optimization to keep mounted only last few screens in the stack. // We keep the last full screen and the one before it to avoid unmounting persistent screens // (like ReportsSplitNavigator) which contain heavy component trees (e.g. LHN with thousands of items). -export default function useCustomRootStackNavigatorState({state, persistentScreens}: CustomStateHookProps) { +export default function useCustomRootStackNavigatorState({state}: CustomStateHookProps) { const lastSplitIndex = state.routes.findLastIndex((route) => isFullScreenName(route.name)); const indexToSlice = Math.max(0, lastSplitIndex - 1); - - if (indexToSlice === 0) { - return {...state, routes: state.routes, index: state.routes.length - 1}; - } - - // Collect persistent routes that fell outside the slice window - const persistentScreensSet = persistentScreens ? new Set(persistentScreens) : undefined; - const persistentRoutesBefore = []; - for (let i = 0; i < indexToSlice; i++) { - const route = state.routes.at(i); - if (route && persistentScreensSet?.has(route.name)) { - persistentRoutesBefore.push(route); - } - } - - const slicedRoutes = state.routes.slice(indexToSlice); - const routesToRender = persistentRoutesBefore.length > 0 ? [...persistentRoutesBefore, ...slicedRoutes] : slicedRoutes; - + const routesToRender = state.routes.slice(indexToSlice, state.routes.length); return {...state, routes: routesToRender, index: routesToRender.length - 1}; } diff --git a/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.tsx b/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.tsx index 4a7fc98d8f33..730e269d507a 100644 --- a/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.tsx +++ b/src/libs/Navigation/PlatformStackNavigation/createPlatformStackNavigatorComponent/index.tsx @@ -73,9 +73,8 @@ function createPlatformStackNavigatorComponent; displayName: string; parentRoute?: RouteProp; - persistentScreens?: string[]; }; // Props for the custom state hook.