Split contexts to state and actions - Batch 4#83454
Conversation
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
|
@mkhutornyi 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] |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 573a75d193
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
|
||
| const value = useMemo(() => ({isMouseDownOnInput, setMouseDown, setMouseUp}), [isMouseDownOnInput]); | ||
| const stateValue = {isMouseDownOnInput}; | ||
| const actionsValue = {setMouseDown, setMouseUp}; |
There was a problem hiding this comment.
Memoize mouse actions context value
MouseActionsContext now receives a fresh object on every MouseProvider render, so components that only call useMouseActions() still re-render whenever isMouseDownOnInput toggles. This defeats the state/actions split and can reintroduce the same UI churn this migration is trying to remove (for example, NumberWithSymbolForm will still update on mouse down/up transitions), so the actions context should keep a stable value identity across unrelated state updates.
Useful? React with 👍 / 👎.
JmillsExpensify
left a comment
There was a problem hiding this comment.
Looks good from a product perspective.
|
I got one-time crash when typing on search. Not reproducible anymore. Screen.Recording.2026-02-27.at.2.47.25.pm.mov |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppAndroid: mWeb ChromeiOS: HybridAppiOS: mWeb SafariMacOS: Chrome / SafariScreen.Recording.2026-02-27.at.2.43.35.pm.movScreen.Recording.2026-02-27.at.2.44.40.pm.mov |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 573a75d193
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const stateValue = {isMouseDownOnInput}; | ||
| const actionsValue = {setMouseDown, setMouseUp}; |
There was a problem hiding this comment.
Memoize mouse context values to avoid list-wide rerenders
MouseProvider now constructs stateValue and actionsValue inline on every render, so both context value props change identity even when isMouseDownOnInput is unchanged. Because React context updates are identity-based, any parent rerender of this provider now forces all useMouseState/useMouseActions consumers (e.g., selection list items in the money request flow) to rerender unnecessarily, which is a measurable regression from the previous memoized behavior and can cause interaction lag on large lists.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
The component is memoized by the React Compiler
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚧 @mountiny has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/mountiny in version: 9.3.28-0 🚀
|
|
🚀 Deployed to staging by https://github.com/mountiny in version: 9.3.30-0 🚀
|
|
🚀 Deployed to production by https://github.com/blimpich in version: 9.3.30-3 🚀
|
cc: @mountiny
Explanation of Change
Migration of the following contexts to follow state/actions split pattern:
Fixed Issues
$ #80271
PROPOSAL:
Tests
Prerequisites
Steps
Settings -> Profileand press any of the MenuItems, see if RHP opens correctly+->Create Expense->Manualand long press on the currency amount. Upon releasing the button the input should still be focusedOffline tests
QA Steps
Prerequisites
Steps
Settings -> Profileand press any of the MenuItems, see if RHP opens correctly+->Create Expense->Manualand long press on the currency amount. Upon releasing the button the input should still be focusedPR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso 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
Screen.Recording.2026-02-27.at.12.14.31.mov
iOS: mWeb Safari
MacOS: Chrome / Safari
Screen.Recording.2026-02-26.at.14.53.56.mov