/** * 页面流转监控工具函数 * * 提供开箱即用的接入辅助,业务层直接引用,不强依赖各路由库的类型。 * 本文件不使用 React Hooks,避免对 react-hooks/rules-of-hooks 的依赖。 * * ## 接入方式对照 * * | 路由框架 | 推荐 API | 说明 | * |----------------------|-----------------------------------|------------------------------------------------| * | React Navigation | createReactNavigationIntegration | onReady 时注册,内部用 addListener 订阅,更健壮 | * | Expo Router | useAegisPageView(Hook) | 通过 usePathname() 监听,Expo Router 推荐方式 | * | react-router-native v5 | createNativeRouterListener | 订阅 history.listen,自动补发首屏 PV | * | react-router-native v6 | useAegisPageView(Hook) | 通过 useLocation().pathname 监听 | * | **任意框架(兜底)** | **useAegisPageView(Hook)** | 只要能获取到 pathname 字符串即可使用,不依赖特定路由库 | * * > **兜底建议**:如果你的路由框架不在上表中,或上述专用 API 不适用, * > 直接使用 `useAegisPageView(aegis, pathname)` 即可。 * > 它自动处理首屏 PV 上报和去重,只需要一个 pathname 字符串。 */ import Aegis from '../aegis'; interface ReactNavigationIntegration { /** * 在 NavigationContainer onReady 中调用,完成注册。 * 同时支持传入 ref 对象(自动读 .current)或直接传入 container 实例。 */ registerNavigationContainer: (containerOrRef: unknown) => void; /** * 兜底手动上报(无法使用自动集成时) */ reportManual: (routeName: string) => void; } /** * 创建 React Navigation 集成对象(两阶段注册) * * 灵感来自 Sentry react-native SDK 的 reactNavigationIntegration 设计: * - 阶段一:createReactNavigationIntegration(aegis) 创建集成,此时不解析 ref * - 阶段二:NavigationContainer.onReady 中调用 integration.registerNavigationContainer(ref) * 此时 ref.current 必然有值,彻底解决 ref 为 undefined 的问题 * * 内部通过 container.addListener('state', cb) 订阅路由变化, * 不需要业务层传 onStateChange prop,接入更干净。 * * @param aegis Aegis 实例 * @returns ReactNavigationIntegration 对象 * * @example * import { createNavigationContainerRef } from '@react-navigation/native'; * import { createReactNavigationIntegration } from '@tencent/aegis-rn-sdk'; * * const navigationRef = createNavigationContainerRef(); * const navIntegration = createReactNavigationIntegration(aegis); * * { * // onReady 时 ref.current 必然不为 null * navIntegration.registerNavigationContainer(navigationRef); * }} * > * * // 没有 ref 时的兜底 * navIntegration.reportManual('HomeScreen'); */ export declare const createReactNavigationIntegration: (aegis: Aegis) => ReactNavigationIntegration; /** * @deprecated 请使用 createReactNavigationIntegration 替代。 * 旧 API 保留以向后兼容,内部仍走 onReady/onStateChange 模式。 */ export declare const createReactNavigationListener: (aegis: Aegis, navigationRef: { getCurrentRoute: () => { name?: string; } | undefined; }) => { onReady: () => void; onStateChange: () => void; }; /** * 创建 react-router-native 的 history 监听器。 * 订阅 history 对象的 listen 事件,路由变化时自动上报 PV。 * 注册时会立即上报当前路由作为首屏 PV,避免 spa 模式下首屏丢失。 * * **⚠️ 仅适用于 react-router-native v5。** * v6 已移除 `useHistory` / `history` 对象,请改用 `useAegisPageView` Hook: * * @example * // react-router-native v6 推荐用法 * import { useLocation } from 'react-router-native'; * import { useAegisPageView } from 'aegis-rn-sdk'; * * function AegisRouteTracker() { * const { pathname } = useLocation(); * useAegisPageView(aegis, pathname); * return null; * } * * @example * // react-router-native v5 用法 * import { useHistory } from 'react-router-native'; * import { createNativeRouterListener } from 'aegis-rn-sdk'; * * function AegisRouteTracker() { * const history = useHistory(); * useEffect(() => { * const unlisten = createNativeRouterListener(aegis, history); * return unlisten; * }, [history]); * return null; * } * * @param aegis Aegis 实例 * @param history react-router-native v5 的 history 对象 * @returns unlisten 函数,组件卸载时调用以取消监听 */ export declare const createNativeRouterListener: (aegis: Aegis, history: { listen: (cb: (...args: any[]) => void) => () => void; location?: { pathname: string; } | undefined; }) => (() => void); export {};