Navigation state is properly managed at the root
Why it matters
Without root-level state tracking, analytics firing on screen changes, auth-gated redirects, and deep-link-driven UI toggles all become per-screen boilerplate that drifts out of sync. Missing onStateChange means you cannot detect when a user lands on a sensitive screen to refresh a token, or log funnel events centrally. The app ends up with duplicated tracking code and screens that never tell the rest of the app where the user is.
Severity rationale
Medium because the app still navigates, but cross-screen analytics and global side effects become unreliable or duplicated.
Remediation
Attach an onStateChange handler to NavigationContainer so analytics and global reactions fire in one place. Keep the latest state in a ref or store so any screen can read it:
<NavigationContainer
linking={linking}
onStateChange={(state) => {
const route = state?.routes[state.index]
analytics.track('screen_view', { name: route?.name })
}}
>
<RootNavigator />
</NavigationContainer>
Put the handler in src/navigation/index.tsx so it ships with the container.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Mobile Navigation & Deep Linking Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
Taxons
History
- 2026-04-18·v1.0.0·Initial import from mobile-navigation-linking·automated