refactor(stake): use native stack navigators for Stake routes#30220
refactor(stake): use native stack navigators for Stake routes#30220weitingsun wants to merge 4 commits into
Conversation
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
| name={Routes.STAKING.STAKE} | ||
| component={EarnInputView} | ||
| options={{ headerShown: false }} | ||
| /> |
There was a problem hiding this comment.
UNSTAKE route gets header flicker after native stack migration
Medium Severity
The UNSTAKE route's component (EarnWithdrawInputView) still configures its header via useEffect + navigation.setOptions(getStakingNavbar(...)). Migrating the navigator from createStackNavigator to createNativeStackNavigator introduces the exact visible header flicker the PR describes and fixes for other screens. The UNSTAKE route lacks headerShown: false and an in-screen HeaderStandard, so the default native header renders first, then gets replaced on the next frame by the JS-configured header.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit f194b46. Configure here.
There was a problem hiding this comment.
I am leaving this out on purpose because EarnWithdrawInputView seems to be doing more with their navbar so I am leaving this to the team to migrate over to HeaderStandard
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a2c1345. Configure here.
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection:
SmokeStake is selected because these changes directly affect the stake entry, stake confirmation, unstake confirmation, and earnings history views - the core staking flows. SmokeConfirmations is selected per the SmokeStake tag description: "When selecting SmokeStake, also select SmokeConfirmations (transaction confirmations are part of the flow)." The StakeConfirmationView and UnstakeConfirmationView are confirmation screens that are part of the staking flow. No other tags are needed as the changes are scoped to the Stake/Earn UI components and don't touch shared navigation infrastructure, browser, accounts, network, or other feature areas. Performance Test Selection: |
|
Matt561
left a comment
There was a problem hiding this comment.
@weitingsun When testing, the withdrawal screen (staking and lending) renders with iOS' "glass" buttons in the header.





Description
Migrates the Stake screen and modal navigators from @react-navigation/stack to @react-navigation/native-stack(POC), and replaces getStakingNavbar + useEffect(setOptions(...)) with an in-screen HeaderStandard on three Stake flows.
Why: Setting headers via useEffect + setOptions on native stack causes a visible flicker on first paint (the default native header renders, then is replaced); for these screens we now configure headerShown: false at the route level and render the header in-screen with HeaderStandard, which eliminates the flicker.
What changed
StakeConfirmationView, UnstakeConfirmationView, StakeEarningsHistoryView: replaced legacy header setup with HeaderStandard; back button preserves the existing analytics events (STAKE_CONFIRMATION_BACK_CLICKED, UNSTAKE_CONFIRMATION_BACK_CLICKED) via useAnalytics.
Note I am leaving migration EarnWithDrawInputView.tsx out on purpose because this navbar has more logic so it's better for the team to do the migration
UnstakeConfirmationView.styles.ts: mainContainer height: '100%' → flex: 1 so the footer (Cancel / Continue) lays out correctly under the new flex parent + HeaderStandard.
EarnInputView: removed the now-redundant useEffect(() => navigation.setOptions({ headerShown: false })) (the route owns it).
Tests: navigation mocks now include goBack; StakeEarningsHistoryView.test.tsx was rewritten to assert on the rendered header title instead of setOptions / getStakingNavbar (which the screen no longer calls).
Android test build: https://github.com/MetaMask/metamask-mobile/actions/runs/25891826048
Changelog
CHANGELOG entry:null
Related issues
Fixes:
Manual testing steps
Screenshots/Recordings
Please note that some of these flows are not representing what app is behaving right now. I hardcoded some of the screens to see the navigation behaviours
Before
After
Pre-merge author checklist
Performance checks (if applicable)
trace()for usage andaddTokenfor an exampleFor performance guidelines and tooling, see the Performance Guide.
Pre-merge reviewer checklist
Note
Medium Risk
Navigation stack implementation and header rendering for core staking flows are changed, which could impact screen transitions, header visibility, and back-navigation/analytics if misconfigured. Changes are localized to Stake/Earn staking screens with updated tests covering the new back behavior.
Overview
Stake navigation is migrated from
@react-navigation/stackto@react-navigation/native-stack, including modal presentation options viaclearNativeStackNavigatorOptions+transparentModalScreenOptionsand defaultheaderShadowVisible: false.Three Stake screens (
StakeConfirmationView,UnstakeConfirmationView,StakeEarningsHistoryView) now renderHeaderStandardin-screen with route-levelheaderShown: false, moving back-button analytics tracking into explicitonBackhandlers (and adding test IDs for back buttons).EarnInputViewremoves a redundantnavigation.setOptions({ headerShown: false }), andUnstakeConfirmationViewlayout is adjusted (height: '100%'→flex: 1) to fit the new header structure.Tests are updated to stop asserting on
setOptions/getStakingNavbarand instead validate rendered header titles plusgoBack+ analytics event tracking on back presses.Reviewed by Cursor Bugbot for commit d5e6dcc. Bugbot is set up for automated code reviews on this repo. Configure here.