Problem
src/screens/Dashboard.tsx defines the screen map as a module-level constant:
const SCREENS: Record<NavSection, React.ReactNode> = {
wallet: <WalletScreen />,
account: <AccountScreen />,
transactions: <TransactionsScreen />,
soroban: <SorobanScreen />,
network: <NetworkScreen />,
};
All five screen components are instantiated as JSX elements when this constant is evaluated — at module import time, before Dashboard even mounts. Every screen's useEffect hooks fire immediately: TransactionHistory fetches history, FeeEstimator fetches fees, ClaimableBalanceCard fetches claimable balances, and ContractEventFeed starts polling — all for screens the user has never visited.
Two more problems: (1) since all screens remain mounted permanently, navigating away from a screen does not unmount it — polling intervals and stale subscriptions accumulate for the session lifetime; (2) state (e.g. SorobanPanel's form inputs) persists across navigation trips, which may be surprising to users.
Solution
Replace the static constant with conditional rendering inside Dashboard, so only the active screen mounts:
<main className="flex-1 overflow-y-auto">
<div className="max-w-[700px] mx-auto px-6 py-8 sm:px-10 sm:py-10">
{active === "wallet" && <WalletScreen />}
{active === "account" && <AccountScreen />}
{active === "transactions" && <TransactionsScreen />}
{active === "soroban" && <SorobanScreen />}
{active === "network" && <NetworkScreen />}
</div>
</main>
Acceptance Criteria
Note for Contributors: If you're assigned to this issue, write a clear and detailed description for your pull request. Explain what was changed, why it was needed, how it was implemented, and include any relevant testing or screenshots where applicable.
Problem
src/screens/Dashboard.tsxdefines the screen map as a module-level constant:All five screen components are instantiated as JSX elements when this constant is evaluated — at module import time, before
Dashboardeven mounts. Every screen'suseEffecthooks fire immediately:TransactionHistoryfetches history,FeeEstimatorfetches fees,ClaimableBalanceCardfetches claimable balances, andContractEventFeedstarts polling — all for screens the user has never visited.Two more problems: (1) since all screens remain mounted permanently, navigating away from a screen does not unmount it — polling intervals and stale subscriptions accumulate for the session lifetime; (2) state (e.g.
SorobanPanel's form inputs) persists across navigation trips, which may be surprising to users.Solution
Replace the static constant with conditional rendering inside
Dashboard, so only the active screen mounts:Acceptance Criteria
useEffectfires for screens the user has never visitedContractEventFeedpolling interval is cleaned up whenSorobanScreenunmounts