import { useEffect, useRef } from 'react'; import { getAnalytics } from '../core/AnalyticsManager'; /** * Hook that auto-tracks screen views from React Navigation. * * Attach the returned `onStateChange` and `ref` to your NavigationContainer: * * ```tsx * const { ref, onStateChange } = useReactNavigationTracking(); * * * ... * * ``` */ export function useReactNavigationTracking(options?: { /** Custom function to extract screen name from navigation state */ getActiveRouteName?: (state: any) => string | undefined; /** Extra properties to attach to every screen event */ extraProperties?: Record; }) { const navigationRef = useRef(null); const routeNameRef = useRef(undefined); const getActiveRouteName = options?.getActiveRouteName ?? defaultGetActiveRouteName; const onStateChange = (state: any) => { const currentRoute = getActiveRouteName(state); const previousRoute = routeNameRef.current; if (currentRoute && currentRoute !== previousRoute) { try { getAnalytics().screen(currentRoute, { previous_screen: previousRoute, ...options?.extraProperties, }); } catch { // Analytics not yet initialized — skip silently } } routeNameRef.current = currentRoute; }; useEffect(() => { // Track initial screen on mount if (navigationRef.current) { const state = navigationRef.current.getRootState?.(); if (state) { routeNameRef.current = getActiveRouteName(state); if (routeNameRef.current) { try { getAnalytics().screen(routeNameRef.current, options?.extraProperties); } catch { // ignore } } } } }, []); return { ref: navigationRef, onStateChange }; } /** * Recursively finds the active route name from a navigation state object. */ function defaultGetActiveRouteName(state: any): string | undefined { if (!state) return undefined; const route = state.routes?.[state.index]; if (!route) return undefined; if (route.state) { return defaultGetActiveRouteName(route.state); } return route.name; } /** * Standalone helper: get active screen name from navigation state. * Useful if you need to read the screen name outside of a hook. */ export { defaultGetActiveRouteName as getActiveRouteName };