You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 23:24:05