如何在React Native Expo中统计各页面停留时长并监听应用关闭
Expo 页面停留时长统计与应用关闭检测实现方案
一、页面停留时长统计实现
你使用的是React Navigation路由体系,不需要单独给每个页面嵌入计时器,通过全局监听路由生命周期事件即可实现统计,无需修改现有navigation.navigate跳转逻辑:
- 监听路由的
focus(页面进入激活)和blur(页面失活离开)事件,全局维护当前激活页面的名称和进入时间戳 - 每次路由切换时,先计算上一个页面的停留时长(当前时间戳 - 上一页面进入时间戳),再更新当前页面的信息
- 统计到的停留时长可直接上报到你的自研统计后台
参考实现代码:
import { NavigationContainer } from '@react-navigation/native'; import { useRef } from 'react'; export default function App() { const navigationRef = useRef(null); // 全局存储当前激活页面的信息 const currentPageInfo = useRef({ name: '', enterTime: 0 }); return ( <NavigationContainer ref={navigationRef} onReady={() => { // 初始化首屏页面的进入时间 const initialRoute = navigationRef.current.getCurrentRoute(); currentPageInfo.current = { name: initialRoute.name, enterTime: Date.now() }; }} onStateChange={() => { const currentRoute = navigationRef.current.getCurrentRoute(); const previousPage = currentPageInfo.current; // 路由变化时先统计上一个页面的停留时长 if (previousPage.name && previousPage.name !== currentRoute.name) { const stayDuration = Date.now() - previousPage.enterTime; // 此处替换为你的上报逻辑,stayDuration单位为毫秒 console.log(`页面${previousPage.name}停留时长:${stayDuration}ms`); } // 更新当前页面信息 currentPageInfo.current = { name: currentRoute.name, enterTime: Date.now() }; }} > {/* 原有导航栈配置保持不变 */} </NavigationContainer> ); }
如果存在弹窗、分屏等不触发路由变化的临时离开页面场景,在对应组件的useEffect销毁回调中单独补充统计逻辑即可。
二、应用关闭/会话结束检测实现
Expo环境下直接使用React Native官方的AppState API即可检测应用状态变化,覆盖用户切后台、主动关闭应用的场景:
- AppState共有三类状态:
active(应用前台活跃)、background(应用切到后台)、inactive(iOS独有,临时非活跃状态如接电话、下拉通知栏) - 当状态从
active变为background时,即可判定会话即将结束,此时统计当前激活页面的停留时长,同时记录会话结束时间戳上报 - 可自定义会话中断阈值:如果应用切后台超过阈值(比如30分钟)再切回前台,判定为新会话;短时间切回则延续原有会话统计即可
参考实现代码:
import { AppState } from 'react-native'; import { useEffect } from 'react'; // 在根组件中添加该监听逻辑 useEffect(() => { const appStateListener = AppState.addEventListener('change', (nextAppState) => { // 应用从活跃切到后台(含用户主动关闭应用的场景) if (AppState.currentState === 'active' && nextAppState === 'background') { const currentPage = currentPageInfo.current; if (currentPage.name) { const stayDuration = Date.now() - currentPage.enterTime; // 上报当前页面停留时长 console.log(`会话结束,页面${currentPage.name}停留时长:${stayDuration}ms`); // 上报会话结束时间戳 const sessionEndTime = Date.now(); } } // 应用从后台切回前台,恢复统计 if (AppState.currentState.match(/inactive|background/) && nextAppState === 'active') { // 此处可添加阈值判断逻辑,超过阈值则初始化新会话 currentPageInfo.current.enterTime = Date.now(); } }); return () => { appStateListener.remove(); }; }, []);
iOS端用户上滑关闭应用、Android端用户主动结束应用进程都会先触发background状态,该逻辑可覆盖99%以上的会话结束场景。
内容的提问来源于stack exchange,提问作者Muhammad Altaaf Ackbar
相关产品推荐
相关产品推荐

