Split contexts to state and actions - Batch 2#81986
Split contexts to state and actions - Batch 2#81986mountiny merged 24 commits intoExpensify:mainfrom
Conversation
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
|
Oh the scope of this PR is super large. Can we separate into small PRs per each context and provider? |
Hey @mkhutornyi! Actually that's the point of the migration to migrate many context providers at once - these are almost only repetitive changes that should not affect any logic and behaviour of the context consumers cc: @mountiny |
100a1dd to
772edd1
Compare
|
@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] |
| return currencyListRef.current[currencyCode]?.symbol; | ||
| }, []); | ||
|
|
||
| const getCurrencyDecimals = useCallback( |
There was a problem hiding this comment.
❌ CLEAN-REACT-PATTERNS-5 (docs)
getCurrencyDecimals captures currencyList directly in its closure (line 24) and lists it as a dependency ([currencyList]), so it gets a new identity every time the currency list changes. This causes actionsValue to update on every currencyList change, which re-renders all consumers of useCurrencyListActions() — defeating the purpose of the state/actions split.
getCurrencySymbol on line 18 already solves this correctly by reading from currencyListRef.current with an empty dependency array.
Apply the same ref pattern to getCurrencyDecimals:
const getCurrencyDecimals = useCallback(
(currencyCode: string | undefined): number => {
const decimals = currencyListRef.current[currencyCode ?? ""]?.decimals;
return decimals ?? 2;
},
[],
);Please rate this suggestion with 👍 or 👎 to help us improve! Reactions are used to monitor reviewer efficiency.
There was a problem hiding this comment.
This code has been taken without any changes from the original Provider
|
Please fix lint errors |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.2026-02-17.at.10.20.53.am.movAndroid: mWeb ChromeiOS: HybridAppScreen.Recording.2026-02-17.at.9.57.21.am.moviOS: mWeb SafariMacOS: Chrome / SafariScreen.Recording.2026-02-17.at.9.58.55.am.mov |
|
Everything should be fine now! 🤞🏻 |
mkhutornyi
left a comment
There was a problem hiding this comment.
For newly added components, please remove manual memoization (if component is not react compilable, fix it first).
For new/updated hooks, please try to add unit tests as much as possible.
| // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call -- hooks return typed state/actions; type resolution fails from re-exports | ||
| const {isRootStatusBarEnabled}: CustomStatusBarAndBackgroundStateContextType = useCustomStatusBarAndBackgroundState(); | ||
| // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call -- hooks return typed state/actions; type resolution fails from re-exports |
There was a problem hiding this comment.
why lint error here? can we prevent in first place?
| import ConfirmModal from '../ConfirmModal'; | ||
| import RenderHTML from '../RenderHTML'; |
| * const { dispatch } = useMultifactorAuthenticationActions(); | ||
| * dispatch({ type: 'SET_VALIDATE_CODE', payload: '123456' }); |
|
Hey @mkhutornyi! I addressed the comments, added some tests, and removed |
|
Codex Review: Didn't find any major issues. Bravo. ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
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". |
|
🚧 @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.21-0 🚀
|
|
🚀 Deployed to production by https://github.com/mountiny in version: 9.3.21-4 🚀
|
| currencyListRef.current = currencyList; | ||
|
|
||
| const getCurrencySymbol = useCallback((currencyCode: string): string | undefined => { | ||
| return currencyListRef.current[currencyCode]?.symbol; |
There was a problem hiding this comment.
Hey! This code has been taken without any changes from the original Provider, so the only thing I did was to rearrange it slightly without introducing the ref
Explanation of Change
Migration of the following contexts to follow state/actions split pattern:
Fixed Issues
$ #80271
PROPOSAL:
Tests
Prerequisites
Test
Offline tests
QA Steps
Prerequisites
Test
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectioncanBeMissingparam foruseOnyxtoggleReportand 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
Screen.Recording.2026-02-16.at.11.49.08.mov
Android: mWeb Chrome
iOS: Native
Screen.Recording.2026-02-16.at.10.03.44.mov
iOS: mWeb Safari
MacOS: Chrome / Safari
Screen.Recording.2026-02-16.at.09.48.14.mov