帮你快速理解、总结文档立即下载

API 说明

最近更新时间:2026-11-03 19:54:02
本文档已由 AI 辅助审校
我的收藏
本文详细介绍用户体验监控 React Native SDK(tdem-rn-sdk)的各功能接口,帮助您更灵活、深度地使用 SDK。初始化参数与各采集开关说明请参见 SDK 初始化。同一应用内请复用初始化创建的 tdem 实例,切勿在每次上报时重复调用 new TDEM。

自定义事件、测速与异常上报

初始化完成后,可调用以下接口上报自定义事件、耗时、已处理异常,以及用户 / 设备标识与全局标签。下面是一组常用调用示例,各方法的参数、返回值与说明见下表。
tdem.track('add_to_cart', {
tags: {channel: 'app'},
properties: {sku: 'DEMO-SKU'},
});
tdem.trackStruggle('repeat_submit', {
severity: 'high',
tags: {page: 'checkout'},
});
tdem.measure('load_profile', 128, {tags: {source: 'cache'}});
tdem.startMeasure('render_profile');
// 执行待测速的业务操作
tdem.endMeasure('render_profile', {properties: {result: 'ok'}});
tdem.captureException(new Error('checkout test failure'));
tdem.setUser('test-user');
tdem.clearUser();
tdem.setDeviceId('host-device-id');
tdem.clearDeviceId();
tdem.setTags({channel: 'demo', group: 'B'});
tdem.removeTags(['group']);
tdem.clearTags();
方法签名
参数
返回值
功能说明
track(name, options?)
name: string;options?: TrackOptions
void
上报业务自定义事件,可携带 tags 与 properties。
trackStruggle(name, options?)
name: string;options?: TrackStruggleOptions
void
业务主动上报自定义挣扎事件,可通过 severity 指定严重程度(可选小写 low / medium / high,默认 medium),不影响自动挣扎检测规则。
measure(name, duration, options?)
name: string;duration: number(毫秒,须在 0..2147483646);options?: MeasureOptions
void
经 reportTDEMEvent 上报已知耗时,不再调用原生 TDEMRn.measure。落库为 event_type: 'custom'、event_category: 'custom',名字在 event_name,耗时在 measurements.duration。tags / properties 按 Web SDK 同样转成字符串,单值最长 1024。请勿按 event_type=measure 在控制台检索。
startMeasure(name) / endMeasure(name, options?)
name: string;options?: MeasureOptions
void
成对计时,同样经 reportTDEMEvent 落成上述 custom 测速事件。重复调用 startMeasure 会保留第一次起始时间并打警告;没有配对的 endMeasure 只打警告、不上报。
captureException(error)
error 为 Error 或 string
void
经 reportTDEMEvent 上报已处理的 JS 异常(event_type: 'js_error',event_category: 'error'),mechanism_type: 'manual',mechanism_handled: 1,exception_frames 来自 parseErrorStack(Error.stack)。传入字符串时先包成 new Error(string)。不再走原生手动崩溃通道,也不会向业务代码重新抛出。
setUser(userId) / clearUser()
userId: string / 无参
void
动态设置或清除业务用户标识,仅作用于后续事件,不会拆分或新建会话。
setDeviceId(deviceId) / clearDeviceId()
deviceId: string / 无参
void
动态设置或清除宿主设备标识,透传给原生层;未设置时原生上报 not_set,请勿在 JS 侧自行生成。
setTags(tags) / removeTags(keys) / clearTags()
tags: Record<string, unknown>;keys 为字符串或字符串数组
void
设置、按名移除或清空全局标签,随后续事件一并上报。
说明:
TrackOptions 与 MeasureOptions 中的 tags 和 properties 类型均为 Record<string, unknown>。返回 void 仅表示调用已交由原生通道处理,不代表服务端已落库。
track 与 trackStruggle 仍直连原生层,原生会按平台规则丢字段或整单丢弃。事件名去空白后不能为空,且不超过128个字符。
Android 上 properties 的 key 须匹配 ^[a-z0-9_]{1,128}$,不合规的 key 会被静默丢弃;命中 password、token、authorization、cookie、secret 时整条事件被拒绝。
iOS 上 tags 与 properties 的 key 均须匹配 ^[A-Za-z0-9_.-]{1,64}$,非法 key 或敏感 key 都会导致整条事件被拒绝;iOS 只保留字符串和数字类型的值。请使用小写字母、数字和下划线作为 Android properties 的 key。
上方示例中的 channel、sku 符合上述规则。
measure、endMeasure、captureMessage 与 captureException 经 reportTDEMEvent 上报,不经过上述原生自定义事件 key 校验。

页面管理与路由集成

以下示例演示手动页面浏览上报、读取当前页面,以及原生逻辑页面栈接口。同一次路由跳转请只使用其中一种方式。
tdem.reportPageView('/checkout', {page_title: 'Checkout'});
// 或调用 tdem.setPage('/checkout');同一次路由跳转请勿同时调用两者
const currentPage = tdem.getCurrentPage();
// 或使用显式原生页面栈生命周期接口:
tdem.startPage('/product');
tdem.leavePage();
页面替换与手动 PV(reportPageView / setPage):
开启 spa: true 且采样命中、spa 插件挂载后:reportPageView 在路径为空、命中 spa.ignore、或与上一次路由名相同时不会通知原生;setPage 不走 ignore、也不去重,仍会通知原生替换当前页面并发出 page_view。未挂载 spa 插件时,两者都会通知原生。同一次页面跳转请只调用其中之一。
应用进入后台或变为 inactive 时,SDK 会再上报一条 _background_ 页面;回到前台时会把离开前的页面再报一次。验证 page_view 顺序时,若中途切过后台,时间轴不会只包含业务路由。
页面路径请始终通过第一个参数 pageUrl(非空字符串)传入,页面标题通过 options.page_title 传入(当前类型声明中虽包含 options.page_url,但运行时不会读取该字段覆盖页面路径)。
getCurrentPage() 返回 JS 层记录的当前页面名称;直接调用原生 startPage 时不会同步更新该 JS 缓存值。
原生逻辑页面栈(startPage / leavePage):
透传调用原生 SDK 的逻辑页面入栈与出栈接口(需按 LIFO 顺序成对调用)。常规 React Native 应用建议统一使用下方的路由集成工具或 reportPageView,避免混用两套页面管理方式导致重复上报。
除 SDK 初始化 中介绍的 React Navigation 用法外,SDK 还提供以下路由导出工具:
导出项
适用场景与用法说明
createReactNavigationIntegration(tdem)
推荐用于 React Navigation:在 NavigationContainer 的 onReady 中调用 registerNavigationContainer(ref)(或透传 onStateChange),自动解析嵌套导航的叶子路由名;卸载时可调用 .remove() 清理。
createExpoRouterIntegration(tdem)
适用于自定义原生构建的 Expo Router 项目:将 useNavigationContainerRef() 传入 registerNavigationContainer(ref),按 route.key 判重识别动态路由跳转(如 /post/1 → /post/2);注意调用 .remove() 会永久注销该集成实例。
useTDEMPageView(tdem, pathname)
通用 React Hook:在组件中传入当前 pathname 变化自动上报 PV;请勿与容器级路由集成同时启用。

行为采集、构建期标注与隐私控制

开启 behavior: true 并使用 tdem.wrap(App) 包裹根组件后,SDK 按以下优先级解析交互目标标识(target_element):
1. 可读标签:就近读取路径上第一个可读标签:tdem-label → accessibilityLabel → aria-label → testID。
2. Metro 构建期标注(可选,默认关闭):该优先级位于可读标签与组件路径回退之间。配置时机是工程构建配置,不是运行时开关;在 metro.config.js / babel.config.js 中开启,并执行 npx react-native start --reset-cache 后重新加载 JS,才会注入 data-tdem-component / data-tdem-source-file。打开后,该层用于拼路径的组件名会被标注名替换;没有可读标签时,target_element 用这些标注名(以及未标注层的运行时名),不是裸运行时函数名。若传入自定义选项对象,需在 babel.config.js 中同步写成 [require('tdem-rn-sdk/metro-annotate'), options]。
在 metro.config.js 中开启构建期标注:
// metro.config.js
const {withTDEMConfig} = require('tdem-rn-sdk/metro');

module.exports = withTDEMConfig(
{
// 原有 Metro 配置
},
{annotateReactComponents: true},
);
同时在 babel.config.js 中注册标注插件,避免 Metro worker 或缓存漏标 .tsx:
// babel.config.js
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [require('tdem-rn-sdk/metro-annotate')],
};
3. 组件路径回退:仍没有标签时,用非 View / Text 的 name 自外向内以 > 拼接,最多4段。
event_properties.target_class 取触点那一层的 name,不一定等于 target_element。event_properties.source_file 来自标注或 Fiber 调试信息。建议为关键业务按钮配置稳定且不含敏感信息的 accessibilityLabel 或 testID。

手动触发点击采集

配置时机:仅当根组件无法使用 tdem.wrap(App)(例如自定义手势系统)时使用;常规页面点击不需要调用。须已完成初始化、开启 behavior: true,并已通过 canCollect()。在自定义手势的触摸回调中调用 captureClickFromTouch(tdem, touchEvent),传入带 _targetInst 的触摸事件;shouldPatch('behavior') 为 false 或缺少 _targetInst 时不会上报。
import {captureClickFromTouch} from 'tdem-rn-sdk';

function handleTouch(event) {
captureClickFromTouch(tdem, event);
}

状态查询与生命周期控制

方法签名
返回值
平台行为说明
getConfig()
本地 TDEMConfig
返回初始化时传入的本地配置对象,不是远程配置。
getRemoteConfig()
{ enabled, started, tdemSampleRate, replaySampleRate } 或 null
返回原生层回传的远程配置;回调到达前为 null。
isNativeStarted()
boolean
表示原生层 init 回调是否已成功执行。
canCollect()
boolean
表示是否已通过远程配置与会话采样闸门(即允许挂载 JS 插件)。
getSessionId()
Promise<string>
异步读取原生当前会话 ID。Android 仅在原生实例不存在时以 E_NOT_STARTED 拒绝(空会话号仍会成功返回);iOS 在会话号长度为 0 时同样拒绝。调用方需捕获异常。
setLocalSwitch(name, enabled)
void
动态开关 JS 插件(onError / spa / api / behavior);仍受 canCollect() 远程闸门约束。
flush()
Promise<unknown>
iOS 在正确链接 TDEMiOSSDK 时转发原生 flush(未链接返回 E_NOT_WIRED,Promise 完成不代表服务端已落库);Android 桥当前未实现该方法,调用会以 E_UNIMPLEMENTED 拒绝。
stop()
Promise<unknown>
iOS 在正确链接 TDEMiOSSDK 时转发原生 stop(未链接返回 E_NOT_WIRED,不重置会话或清空本地缓存);Android 桥当前未实现该方法,调用会以 E_UNIMPLEMENTED 拒绝。
注意:
SDK 遵循所在操作系统(Android / iOS)的原生会话生命周期:冷启动新建会话,空闲满20分钟或总时长满4小时自动轮换。不提供重置会话(resetSession)接口。在 Android 上请勿将 flush() 或 stop() 作为业务流程依赖。

原始事件上报与过滤钩子

对于高级自定义集成场景,可直接调用 reportTDEMEvent 上报单条或批量符合协议的 TDEMEvent(日常业务埋点请优先使用 track / measure):
tdem.reportTDEMEvent({
event_type: 'custom',
event_category: 'custom',
timestamp: Date.now(),
data: {
event_name: 'integration_check',
measurements: {duration: 120},
},
});
通过初始化配置的 beforeReport 钩子,可在 JS 事件送往原生桥之前按事件类型(SDK 已导出 JS_ERROR_EVENT、PROMISE_ERROR_EVENT、API_CALL_EVENT、API_ERROR_EVENT、CLICK_EVENT、SCROLL_EVENT、LONG_PRESS_EVENT、MEASURE_EVENT、LOG_EVENT 等常量)进行过滤或裁剪:
const tdem = new TDEM({
id: 'YOUR_APP_ID',
url: 'https://dem.rumt-zh.com',
beforeReport(event) {
if (event.event_type === 'log') return null;
return event;
},
});
说明:
beforeReport 仅作用于经 JS 层 reportTDEMEvent 发送的事件(包括自动采集的 onError、api、behavior 事件,以及 measure、endMeasure、captureException、captureMessage 与手动 reportTDEMEvent),不拦截直接调用原生桥的方法(track、trackStruggle、reportPageView、setPage、startPage、leavePage)以及原生崩溃、原生录屏分段流。