From fc9d7bf81a04499032f5d75e7832e22c9511bd2b Mon Sep 17 00:00:00 2001 From: staszekscp Date: Fri, 16 Jan 2026 08:31:45 +0100 Subject: [PATCH 1/7] Split SearchRouter to State and Actions --- .../SearchPageHeaderInput.tsx | 4 +- .../Search/SearchRouter/SearchButton.tsx | 4 +- .../SearchRouter/SearchRouterContext.tsx | 57 +++++++++++++++---- .../SearchRouter/SearchRouterModal/index.tsx | 5 +- .../Navigation/AppNavigator/AuthScreens.tsx | 4 +- 5 files changed, 55 insertions(+), 19 deletions(-) diff --git a/src/components/Search/SearchPageHeader/SearchPageHeaderInput.tsx b/src/components/Search/SearchPageHeader/SearchPageHeaderInput.tsx index 4ecd440d4a51c..b489fb8bfc840 100644 --- a/src/components/Search/SearchPageHeader/SearchPageHeaderInput.tsx +++ b/src/components/Search/SearchPageHeader/SearchPageHeaderInput.tsx @@ -13,7 +13,7 @@ import {buildSubstitutionsMap} from '@components/Search/SearchRouter/buildSubsti import type {SubstitutionMap} from '@components/Search/SearchRouter/getQueryWithSubstitutions'; import {getQueryWithSubstitutions} from '@components/Search/SearchRouter/getQueryWithSubstitutions'; import {getUpdatedSubstitutionsMap} from '@components/Search/SearchRouter/getUpdatedSubstitutionsMap'; -import {useSearchRouterContext} from '@components/Search/SearchRouter/SearchRouterContext'; +import {useSearchRouterActions} from '@components/Search/SearchRouter/SearchRouterContext'; import type {SearchQueryJSON, SearchQueryString} from '@components/Search/types'; import type {SearchQueryItem} from '@components/SelectionListWithSections/Search/SearchQueryListItem'; import {isSearchQueryItem} from '@components/SelectionListWithSections/Search/SearchQueryListItem'; @@ -84,7 +84,7 @@ function SearchPageHeaderInput({queryJSON, searchRouterListVisible, hideSearchRo const textInputRef = useRef(null); const hasMountedRef = useRef(false); const isFocused = useIsFocused(); - const {registerSearchPageInput} = useSearchRouterContext(); + const {registerSearchPageInput} = useSearchRouterActions(); useEffect(() => { hasMountedRef.current = true; diff --git a/src/components/Search/SearchRouter/SearchButton.tsx b/src/components/Search/SearchRouter/SearchButton.tsx index 1dad9fc115d3e..d8dad94238173 100644 --- a/src/components/Search/SearchRouter/SearchButton.tsx +++ b/src/components/Search/SearchRouter/SearchButton.tsx @@ -12,7 +12,7 @@ import {startSpan} from '@libs/telemetry/activeSpans'; import {callFunctionIfActionIsAllowed} from '@userActions/Session'; import Timing from '@userActions/Timing'; import CONST from '@src/CONST'; -import {useSearchRouterContext} from './SearchRouterContext'; +import {useSearchRouterActions} from './SearchRouterContext'; type SearchButtonProps = { style?: StyleProp; @@ -23,7 +23,7 @@ function SearchButton({style, shouldUseAutoHitSlop = false}: SearchButtonProps) const styles = useThemeStyles(); const theme = useTheme(); const {translate} = useLocalize(); - const {openSearchRouter} = useSearchRouterContext(); + const {openSearchRouter} = useSearchRouterActions(); const pressableRef = useRef(null); const expensifyIcons = useMemoizedLazyExpensifyIcons(['MagnifyingGlass']); diff --git a/src/components/Search/SearchRouter/SearchRouterContext.tsx b/src/components/Search/SearchRouter/SearchRouterContext.tsx index 2ae0d27962b1f..003aa72f4c192 100644 --- a/src/components/Search/SearchRouter/SearchRouterContext.tsx +++ b/src/components/Search/SearchRouter/SearchRouterContext.tsx @@ -10,8 +10,11 @@ import SCREENS from '@src/SCREENS'; import type ChildrenProps from '@src/types/utils/ChildrenProps'; import {closeSearch, openSearch} from './toggleSearch'; -type SearchRouterContext = { +type SearchRouterStateContextType = { isSearchRouterDisplayed: boolean; +}; + +type SearchRouterActionsContextType = { openSearchRouter: () => void; closeSearchRouter: () => void; toggleSearch: () => void; @@ -23,8 +26,7 @@ type HistoryState = { isSearchModalOpen?: boolean; }; -const defaultSearchContext: SearchRouterContext = { - isSearchRouterDisplayed: false, +const defaultSearchRouterActionsContext: SearchRouterActionsContextType = { openSearchRouter: () => {}, closeSearchRouter: () => {}, toggleSearch: () => {}, @@ -32,7 +34,11 @@ const defaultSearchContext: SearchRouterContext = { unregisterSearchPageInput: () => {}, }; -const Context = React.createContext(defaultSearchContext); +const SearchRouterStateContext = + React.createContext({isSearchRouterDisplayed: false}); + +const SearchRouterActionsContext = + React.createContext(defaultSearchRouterActionsContext); const isBrowserWithHistory = typeof window !== 'undefined' && typeof window.history !== 'undefined'; const canListenPopState = typeof window !== 'undefined' && typeof window.addEventListener === 'function'; @@ -69,7 +75,7 @@ function SearchRouterContextProvider({children}: ChildrenProps) { return () => window.removeEventListener('popstate', handlePopState); }, []); - const routerContext = useMemo(() => { + const routerActionsContext = useMemo(() => { const openSearchRouter = () => { if (isBrowserWithHistory) { window.history.pushState({isSearchModalOpen: true} satisfies HistoryState, ''); @@ -136,20 +142,49 @@ function SearchRouterContextProvider({children}: ChildrenProps) { }; return { - isSearchRouterDisplayed, openSearchRouter, closeSearchRouter, toggleSearch, registerSearchPageInput, unregisterSearchPageInput, }; - }, [isSearchRouterDisplayed]); + }, []); - return {children}; + const stateContextValue = useMemo( + () => ({isSearchRouterDisplayed}), + [isSearchRouterDisplayed], + ); + + const actionsContextValue = useMemo( + () => (routerActionsContext), + [ + routerActionsContext + ], + ); + + return ( + + + {children} + + + ); } -function useSearchRouterContext() { - return useContext(Context); +function useSearchRouterState() { + return useContext(SearchRouterStateContext); } -export {SearchRouterContextProvider, useSearchRouterContext}; +function useSearchRouterActions() { + return useContext(SearchRouterActionsContext); +} + +export { + SearchRouterContextProvider, + useSearchRouterState, + useSearchRouterActions, +}; diff --git a/src/components/Search/SearchRouter/SearchRouterModal/index.tsx b/src/components/Search/SearchRouter/SearchRouterModal/index.tsx index 16a7799d4005c..c1eba4211f4bf 100644 --- a/src/components/Search/SearchRouter/SearchRouterModal/index.tsx +++ b/src/components/Search/SearchRouter/SearchRouterModal/index.tsx @@ -4,7 +4,7 @@ import FocusTrapForModal from '@components/FocusTrap/FocusTrapForModal'; import Modal from '@components/Modal'; import ScreenWrapperContainer from '@components/ScreenWrapper/ScreenWrapperContainer'; import SearchRouter from '@components/Search/SearchRouter/SearchRouter'; -import {useSearchRouterContext} from '@components/Search/SearchRouter/SearchRouterContext'; +import {useSearchRouterActions, useSearchRouterState} from '@components/Search/SearchRouter/SearchRouterContext'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useViewportOffsetTop from '@hooks/useViewportOffsetTop'; import {isMobileIOS} from '@libs/Browser'; @@ -14,7 +14,8 @@ const isMobileWebIOS = isMobileIOS(); function SearchRouterModal() { const {shouldUseNarrowLayout} = useResponsiveLayout(); - const {isSearchRouterDisplayed, closeSearchRouter} = useSearchRouterContext(); + const {isSearchRouterDisplayed} = useSearchRouterState() + const {closeSearchRouter} = useSearchRouterActions(); const viewportOffsetTop = useViewportOffsetTop(); // On mWeb Safari, the input caret stuck for a moment while the modal is animating. So, we hide the caret until the animation is done. diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx index 2df277ec6da37..c84c91e7eac6b 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -11,7 +11,7 @@ import OpenAppFailureModal from '@components/OpenAppFailureModal'; import OptionsListContextProvider from '@components/OptionListContextProvider'; import PriorityModeController from '@components/PriorityModeController'; import {SearchContextProvider} from '@components/Search/SearchContext'; -import {useSearchRouterContext} from '@components/Search/SearchRouter/SearchRouterContext'; +import {useSearchRouterActions} from '@components/Search/SearchRouter/SearchRouterContext'; import SearchRouterModal from '@components/Search/SearchRouter/SearchRouterModal'; import SupportalPermissionDeniedModalProvider from '@components/SupportalPermissionDeniedModalProvider'; import {WideRHPContext} from '@components/WideRHPContextProvider'; @@ -143,7 +143,7 @@ function AuthScreens() { const {shouldUseNarrowLayout} = useResponsiveLayout(); const rootNavigatorScreenOptions = useRootNavigatorScreenOptions(); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); - const {toggleSearch} = useSearchRouterContext(); + const {toggleSearch} = useSearchRouterActions(); const currentUrl = getCurrentUrl(); const delegatorEmail = getSearchParamFromUrl(currentUrl, 'delegatorEmail'); const [credentials] = useOnyx(ONYXKEYS.CREDENTIALS, {canBeMissing: true}); From fbc3d90c7dd8519cbee9b05092066b586191d69b Mon Sep 17 00:00:00 2001 From: staszekscp Date: Fri, 16 Jan 2026 08:34:56 +0100 Subject: [PATCH 2/7] Fix double import --- src/components/Search/SearchRouter/SearchRouterModal.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/Search/SearchRouter/SearchRouterModal.tsx b/src/components/Search/SearchRouter/SearchRouterModal.tsx index 7bac27c3eb8a7..c1eba4211f4bf 100644 --- a/src/components/Search/SearchRouter/SearchRouterModal.tsx +++ b/src/components/Search/SearchRouter/SearchRouterModal.tsx @@ -9,8 +9,6 @@ import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useViewportOffsetTop from '@hooks/useViewportOffsetTop'; import {isMobileIOS} from '@libs/Browser'; import CONST from '@src/CONST'; -import SearchRouter from './SearchRouter'; -import {useSearchRouterContext} from './SearchRouterContext'; const isMobileWebIOS = isMobileIOS(); From 728c4139cae490d7ac8861c4e17bcd2495011cfb Mon Sep 17 00:00:00 2001 From: staszekscp Date: Fri, 16 Jan 2026 11:42:55 +0100 Subject: [PATCH 3/7] Remove memoisation in SearchRouterContext to allow Compiler do its job --- .../SearchRouter/SearchRouterContext.tsx | 146 ++++++++---------- 1 file changed, 67 insertions(+), 79 deletions(-) diff --git a/src/components/Search/SearchRouter/SearchRouterContext.tsx b/src/components/Search/SearchRouter/SearchRouterContext.tsx index 5a2cfa3abe526..bb7d3156ef599 100644 --- a/src/components/Search/SearchRouter/SearchRouterContext.tsx +++ b/src/components/Search/SearchRouter/SearchRouterContext.tsx @@ -1,4 +1,4 @@ -import React, {useContext, useEffect, useMemo, useRef, useState} from 'react'; +import React, {useContext, useEffect, useRef, useState} from 'react'; import type {AnimatedTextInputRef} from '@components/RNTextInput'; import isSearchTopmostFullScreenRoute from '@libs/Navigation/helpers/isSearchTopmostFullScreenRoute'; import {navigationRef} from '@libs/Navigation/Navigation'; @@ -75,92 +75,80 @@ function SearchRouterContextProvider({children}: ChildrenProps) { return () => window.removeEventListener('popstate', handlePopState); }, []); - const routerActionsContext = useMemo(() => { - const openSearchRouter = () => { - if (isBrowserWithHistory) { - window.history.pushState({isSearchModalOpen: true} satisfies HistoryState, ''); - } - close( - () => { - setIsSearchRouterDisplayed(true); - searchRouterDisplayedRef.current = true; - }, - false, - true, - ); - }; - const closeSearchRouter = () => { - setIsSearchRouterDisplayed(false); - searchRouterDisplayedRef.current = false; - if (isBrowserWithHistory) { - const state = window.history.state as HistoryState | null; - if (state?.isSearchModalOpen) { - window.history.replaceState({isSearchModalOpen: false} satisfies HistoryState, ''); - } + const openSearchRouter = () => { + if (isBrowserWithHistory) { + window.history.pushState({isSearchModalOpen: true} satisfies HistoryState, '',) + } + close( + () => { + setIsSearchRouterDisplayed(true); + searchRouterDisplayedRef.current = true; + }, + false, + true, + ); + }; + const closeSearchRouter = () => { + setIsSearchRouterDisplayed(false); + searchRouterDisplayedRef.current = false; + if (isBrowserWithHistory) { + const state = window.history.state as HistoryState | null; + if (state?.isSearchModalOpen) { + window.history.replaceState({isSearchModalOpen: false} satisfies HistoryState, ''); } - }; - - const startSearchRouterOpenSpan = () => { - startSpan(CONST.TELEMETRY.SPAN_OPEN_SEARCH_ROUTER, { - name: CONST.TELEMETRY.SPAN_OPEN_SEARCH_ROUTER, - op: CONST.TELEMETRY.SPAN_OPEN_SEARCH_ROUTER, - attributes: { - trigger: 'keyboard', - }, - }); - }; - - // There are callbacks that live outside of React render-loop and interact with SearchRouter - // So we need a function that is based on ref to correctly open/close it - // When user is on `/search` page we focus the Input instead of showing router - const toggleSearch = () => { - const searchFullScreenRoutes = navigationRef.getRootState()?.routes.findLast((route) => route.name === NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR); - const lastRoute = searchFullScreenRoutes?.state?.routes?.at(-1); - const isUserOnSearchPage = isSearchTopmostFullScreenRoute() && lastRoute?.name === SCREENS.SEARCH.ROOT; - - if (isUserOnSearchPage && searchPageInputRef.current) { - if (searchPageInputRef.current.isFocused()) { - searchPageInputRef.current.blur(); - } else { - startSearchRouterOpenSpan(); - searchPageInputRef.current.focus(); - } - } else if (searchRouterDisplayedRef.current) { - closeSearchRouter(); + } + }; + + const startSearchRouterOpenSpan = () => { + startSpan(CONST.TELEMETRY.SPAN_OPEN_SEARCH_ROUTER, { + name: CONST.TELEMETRY.SPAN_OPEN_SEARCH_ROUTER, + op: CONST.TELEMETRY.SPAN_OPEN_SEARCH_ROUTER, + attributes: { + trigger: 'keyboard', + }, + }); + }; + + // There are callbacks that live outside of React render-loop and interact with SearchRouter + // So we need a function that is based on ref to correctly open/close it + // When user is on `/search` page we focus the Input instead of showing router + const toggleSearch = () => { + const searchFullScreenRoutes = navigationRef.getRootState()?.routes.findLast((route) => route.name === NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR); + const lastRoute = searchFullScreenRoutes?.state?.routes?.at(-1); + const isUserOnSearchPage = isSearchTopmostFullScreenRoute() && lastRoute?.name === SCREENS.SEARCH.ROOT; + + if (isUserOnSearchPage && searchPageInputRef.current) { + if (searchPageInputRef.current.isFocused()) { + searchPageInputRef.current.blur(); } else { startSearchRouterOpenSpan(); - openSearchRouter(); + searchPageInputRef.current.focus(); } - }; - - const registerSearchPageInput = (ref: AnimatedTextInputRef) => { - searchPageInputRef.current = ref; - }; + } else if (searchRouterDisplayedRef.current) { + closeSearchRouter(); + } else { + startSearchRouterOpenSpan(); + openSearchRouter(); + } + }; - const unregisterSearchPageInput = () => { - searchPageInputRef.current = undefined; - }; + const registerSearchPageInput = (ref: AnimatedTextInputRef) => { + searchPageInputRef.current = ref; + }; - return { - openSearchRouter, - closeSearchRouter, - toggleSearch, - registerSearchPageInput, - unregisterSearchPageInput, - }; - }, []); + const unregisterSearchPageInput = () => { + searchPageInputRef.current = undefined; + }; - const stateContextValue = useMemo( - () => ({isSearchRouterDisplayed}), - [isSearchRouterDisplayed], - ); + const actionsContextValue = { + openSearchRouter, + closeSearchRouter, + toggleSearch, + registerSearchPageInput, + unregisterSearchPageInput, + }; - const actionsContextValue = useMemo( - () => (routerActionsContext), - [ - routerActionsContext - ], - ); + const stateContextValue = {isSearchRouterDisplayed} return ( Date: Fri, 16 Jan 2026 11:43:58 +0100 Subject: [PATCH 4/7] Fix linter --- src/components/Search/SearchRouter/SearchRouterModal.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Search/SearchRouter/SearchRouterModal.tsx b/src/components/Search/SearchRouter/SearchRouterModal.tsx index c1eba4211f4bf..cf54afc93163b 100644 --- a/src/components/Search/SearchRouter/SearchRouterModal.tsx +++ b/src/components/Search/SearchRouter/SearchRouterModal.tsx @@ -3,8 +3,8 @@ import {Dimensions} from 'react-native'; import FocusTrapForModal from '@components/FocusTrap/FocusTrapForModal'; import Modal from '@components/Modal'; import ScreenWrapperContainer from '@components/ScreenWrapper/ScreenWrapperContainer'; -import SearchRouter from '@components/Search/SearchRouter/SearchRouter'; -import {useSearchRouterActions, useSearchRouterState} from '@components/Search/SearchRouter/SearchRouterContext'; +import SearchRouter from './SearchRouter'; +import {useSearchRouterActions, useSearchRouterState} from './SearchRouterContext'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useViewportOffsetTop from '@hooks/useViewportOffsetTop'; import {isMobileIOS} from '@libs/Browser'; From 092408d34f67d086779b4daecf71888a44b3a9b2 Mon Sep 17 00:00:00 2001 From: staszekscp Date: Fri, 16 Jan 2026 15:45:58 +0100 Subject: [PATCH 5/7] Fix prettier --- .../SearchRouter/SearchRouterContext.tsx | 26 +++++-------------- .../Search/SearchRouter/SearchRouterModal.tsx | 6 ++--- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/components/Search/SearchRouter/SearchRouterContext.tsx b/src/components/Search/SearchRouter/SearchRouterContext.tsx index bb7d3156ef599..073f03bf11620 100644 --- a/src/components/Search/SearchRouter/SearchRouterContext.tsx +++ b/src/components/Search/SearchRouter/SearchRouterContext.tsx @@ -33,11 +33,9 @@ const defaultSearchRouterActionsContext: SearchRouterActionsContextType = { unregisterSearchPageInput: () => {}, }; -const SearchRouterStateContext = - React.createContext({isSearchRouterDisplayed: false}); +const SearchRouterStateContext = React.createContext({isSearchRouterDisplayed: false}); -const SearchRouterActionsContext = - React.createContext(defaultSearchRouterActionsContext); +const SearchRouterActionsContext = React.createContext(defaultSearchRouterActionsContext); const isBrowserWithHistory = typeof window !== 'undefined' && typeof window.history !== 'undefined'; const canListenPopState = typeof window !== 'undefined' && typeof window.addEventListener === 'function'; @@ -77,7 +75,7 @@ function SearchRouterContextProvider({children}: ChildrenProps) { const openSearchRouter = () => { if (isBrowserWithHistory) { - window.history.pushState({isSearchModalOpen: true} satisfies HistoryState, '',) + window.history.pushState({isSearchModalOpen: true} satisfies HistoryState, ''); } close( () => { @@ -148,17 +146,11 @@ function SearchRouterContextProvider({children}: ChildrenProps) { unregisterSearchPageInput, }; - const stateContextValue = {isSearchRouterDisplayed} + const stateContextValue = {isSearchRouterDisplayed}; return ( - - - {children} - + + {children} ); } @@ -171,8 +163,4 @@ function useSearchRouterActions() { return useContext(SearchRouterActionsContext); } -export { - SearchRouterContextProvider, - useSearchRouterState, - useSearchRouterActions, -}; +export {SearchRouterContextProvider, useSearchRouterState, useSearchRouterActions}; diff --git a/src/components/Search/SearchRouter/SearchRouterModal.tsx b/src/components/Search/SearchRouter/SearchRouterModal.tsx index cf54afc93163b..d456e095e401d 100644 --- a/src/components/Search/SearchRouter/SearchRouterModal.tsx +++ b/src/components/Search/SearchRouter/SearchRouterModal.tsx @@ -3,18 +3,18 @@ import {Dimensions} from 'react-native'; import FocusTrapForModal from '@components/FocusTrap/FocusTrapForModal'; import Modal from '@components/Modal'; import ScreenWrapperContainer from '@components/ScreenWrapper/ScreenWrapperContainer'; -import SearchRouter from './SearchRouter'; -import {useSearchRouterActions, useSearchRouterState} from './SearchRouterContext'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useViewportOffsetTop from '@hooks/useViewportOffsetTop'; import {isMobileIOS} from '@libs/Browser'; import CONST from '@src/CONST'; +import SearchRouter from './SearchRouter'; +import {useSearchRouterActions, useSearchRouterState} from './SearchRouterContext'; const isMobileWebIOS = isMobileIOS(); function SearchRouterModal() { const {shouldUseNarrowLayout} = useResponsiveLayout(); - const {isSearchRouterDisplayed} = useSearchRouterState() + const {isSearchRouterDisplayed} = useSearchRouterState(); const {closeSearchRouter} = useSearchRouterActions(); const viewportOffsetTop = useViewportOffsetTop(); From b90935c1799238ecfaebda2b22615b604a4d151c Mon Sep 17 00:00:00 2001 From: staszekscp Date: Mon, 19 Jan 2026 12:01:11 +0100 Subject: [PATCH 6/7] Disable unrelated es-lint rules --- src/components/Search/SearchRouter/SearchButton.tsx | 1 + src/components/Search/SearchRouter/SearchRouterContext.tsx | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/components/Search/SearchRouter/SearchButton.tsx b/src/components/Search/SearchRouter/SearchButton.tsx index d8dad94238173..5a4a4c6afc246 100644 --- a/src/components/Search/SearchRouter/SearchButton.tsx +++ b/src/components/Search/SearchRouter/SearchButton.tsx @@ -36,6 +36,7 @@ function SearchButton({style, shouldUseAutoHitSlop = false}: SearchButtonProps) style={[styles.flexRow, styles.touchableButtonImage, style]} shouldUseAutoHitSlop={shouldUseAutoHitSlop} sentryLabel={CONST.SENTRY_LABEL.SEARCH.SEARCH_BUTTON} + // eslint-disable-next-line react-hooks/refs onPress={callFunctionIfActionIsAllowed(() => { pressableRef?.current?.blur(); diff --git a/src/components/Search/SearchRouter/SearchRouterContext.tsx b/src/components/Search/SearchRouter/SearchRouterContext.tsx index 073f03bf11620..58ca77133a7c4 100644 --- a/src/components/Search/SearchRouter/SearchRouterContext.tsx +++ b/src/components/Search/SearchRouter/SearchRouterContext.tsx @@ -138,6 +138,8 @@ function SearchRouterContextProvider({children}: ChildrenProps) { searchPageInputRef.current = undefined; }; + // Because of the React Compiler we don't need to memoize it manually + // eslint-disable-next-line react/jsx-no-constructed-context-values const actionsContextValue = { openSearchRouter, closeSearchRouter, @@ -146,6 +148,8 @@ function SearchRouterContextProvider({children}: ChildrenProps) { unregisterSearchPageInput, }; + // Because of the React Compiler we don't need to memoize it manually + // eslint-disable-next-line react/jsx-no-constructed-context-values const stateContextValue = {isSearchRouterDisplayed}; return ( From ef66bc4b5377c416da32fe0f7a60a920d12177df Mon Sep 17 00:00:00 2001 From: staszekscp Date: Mon, 19 Jan 2026 13:03:23 +0100 Subject: [PATCH 7/7] Remove es-lint error and enable React Compiler for SearchButton.tsx --- .../Search/SearchRouter/SearchButton.tsx | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/components/Search/SearchRouter/SearchButton.tsx b/src/components/Search/SearchRouter/SearchButton.tsx index 5a4a4c6afc246..d14e57374653b 100644 --- a/src/components/Search/SearchRouter/SearchButton.tsx +++ b/src/components/Search/SearchRouter/SearchButton.tsx @@ -27,6 +27,21 @@ function SearchButton({style, shouldUseAutoHitSlop = false}: SearchButtonProps) const pressableRef = useRef(null); const expensifyIcons = useMemoizedLazyExpensifyIcons(['MagnifyingGlass']); + const onPress = () => { + callFunctionIfActionIsAllowed(() => { + pressableRef.current?.blur(); + + Timing.start(CONST.TIMING.OPEN_SEARCH); + Performance.markStart(CONST.TIMING.OPEN_SEARCH); + startSpan(CONST.TELEMETRY.SPAN_OPEN_SEARCH_ROUTER, { + name: CONST.TELEMETRY.SPAN_OPEN_SEARCH_ROUTER, + op: CONST.TELEMETRY.SPAN_OPEN_SEARCH_ROUTER, + }); + + openSearchRouter(); + })(); + }; + return ( { - pressableRef?.current?.blur(); - - Timing.start(CONST.TIMING.OPEN_SEARCH); - Performance.markStart(CONST.TIMING.OPEN_SEARCH); - startSpan(CONST.TELEMETRY.SPAN_OPEN_SEARCH_ROUTER, { - name: CONST.TELEMETRY.SPAN_OPEN_SEARCH_ROUTER, - op: CONST.TELEMETRY.SPAN_OPEN_SEARCH_ROUTER, - }); - - openSearchRouter(); - })} + onPress={onPress} >