Fix - Ensure the focus in the chat switcher does not change when the API results get in#72273
Conversation
|
@DylanDylann Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
Codecov Report❌ Patch coverage is
... and 60 files with indirect coverage changes 🚀 New features to boost your workflow:
|
| useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.ESCAPE, () => { | ||
| onRouterClose(); | ||
| }); | ||
| const updateAndScrollToFocusedIndex = useCallback(() => listRef.current?.updateAndScrollToFocusedIndex(1, true), []); |
There was a problem hiding this comment.
Because we are passing a callback directly it changes on every render which will in turn trigger the effect unnecessarily.
| setTextQuery={setTextAndUpdateSelection} | ||
| updateAutocompleteSubstitutions={updateAutocompleteSubstitutions} | ||
| onHighlightFirstItem={() => listRef.current?.updateAndScrollToFocusedIndex(1)} | ||
| onHighlightFirstItem={updateAndScrollToFocusedIndex} |
There was a problem hiding this comment.
| onHighlightFirstItem={updateAndScrollToFocusedIndex} | |
| onHighlightFirstItem={() => listRef.current?.updateAndScrollToFocusedIndex(1, true)} |
There was a problem hiding this comment.
@FitseTLT you can do like this, no need to define updateAndScrollToFocusedIndex
There was a problem hiding this comment.
Yeah I think I like this suggestion in that it keeps things as simple as possible, can you edit please @FitseTLT?
There was a problem hiding this comment.
a bit confused here @DylanDylann you 👍 my comment above but you are suggesting to revert it. I will explain it again. The effect I am talking about is the one inside SearchAutocompleteList here
App/src/components/Search/SearchAutocompleteList.tsx
Lines 777 to 783 in 8996805
it has a dependency of onHighlightFirstItem so because we are directly providing the callback it changes whenever SearchRouter rerenders which in turn is running this effect which is unwanted behavior. Ofcourse we can remove the dependency with lint suppresser but is that better than what I have done? 🫤
There was a problem hiding this comment.
@FitseTLT I disagree 😞. Since SearchAutocompleteList likely doesn’t use React.memo or any optimization to prevent re-renders when props change, memoizing the callback wouldn’t actually stop unnecessary re-renders of its child components (Read more here). It provides no real benefit. Additionally, the function itself is just a simple wrapper around listRef.current?.updateAndScrollToFocusedIndex(1, true), with no complex logic or heavy computation that would justify memoization.
There was a problem hiding this comment.
@DylanDylann If a component doesn't have a memo implemented it is rendered based on the default react principle of prop change and in this case if you don't use useCallback for the callback whenever SearchRouter is rendered the onHighlightFirstItem prop will be a new one because you are directly defining the callback so it forces SearchAutocompleteList to be rendered and also this effect to run
App/src/components/Search/SearchAutocompleteList.tsx
Lines 777 to 783 in 8996805
Look at the vid below how the effect runs for more than 20 times as opposed to 6 times when using useCallback
2025-10-13.20-57-59.mp4
Regarding the complexity, we already have another useCallback usages for a similar use case with simple complexity here
App/src/components/Search/SearchRouter/SearchRouter.tsx
Lines 296 to 303 in 1d8ab31
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.2025-10-10.at.16.38.52.movAndroid: mWeb ChromeScreen.Recording.2025-10-10.at.16.36.54.moviOS: HybridAppiOS: mWeb SafariScreen.Recording.2025-10-10.at.16.36.05.movMacOS: Chrome / SafariScreen.Recording.2025-10-10.at.16.32.50.movMacOS: DesktopScreen.Recording.2025-10-10.at.16.34.02.mov |
|
NAB: but I left a minor comment: #72273 (comment) |
|
All right I'm going to merge, the comment is a pretty minor thing in the grand scheme of things. |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚀 Deployed to staging by https://github.com/francoisl in version: 9.2.30-0 🚀
|
|
🚀 Deployed to production by https://github.com/mountiny in version: 9.2.30-6 🚀
|
Explanation of Change
Fixed Issues
$ #71777
PROPOSAL: #71777 (comment)
Tests
Precondition: this should be tested only on Web (mac) and Desktop platforms
Offline tests
Same as above
QA Steps
Same as above
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectioncanBeMissingparam foruseOnyxtoggleReportand notonIconClick)src/languages/*files and using the translation methodWaiting for Copylabel for a copy review on the original GH to get the correct copy.STYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel so the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
2025-10-09.23-36-15.mp4
MacOS: Desktop
2025-10-09.23-35-58.mp4