react-track-hooks 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +146 -42
- package/dist/index.cjs.js +384 -70
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +14 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +384 -71
- package/dist/index.esm.js.map +1 -1
- package/dist/trackHooks.d.ts +7 -6
- package/dist/trackHooks.d.ts.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +6 -0
- package/dist/utils.d.ts.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/react-track-hooks)
|
|
4
4
|
[](https://github.com/PassingTraveller111/react-track-hooks/blob/main/LICENSE)
|
|
5
5
|
|
|
6
|
-
一个轻量、易用的 React 埋点 Hooks
|
|
6
|
+
一个轻量、易用的 React 埋点 Hooks 库,支持点击埋点、曝光埋点、页面停留时长埋点、自定义埋点,内置**智能批量上报**和**增强型失败重试**机制,适配 React/Next.js 项目。
|
|
7
7
|
|
|
8
8
|
## 特性
|
|
9
9
|
- 🚀 开箱即用:提供常用埋点场景的 Hooks,无需重复封装
|
|
10
|
-
-
|
|
10
|
+
- 📦 智能批量上报:支持埋点批量入队、定时/定量触发上报,减少网络请求
|
|
11
|
+
- 🔄 增强型失败重试:内置 localStorage 缓存 + 指数退避算法,批量/单条自适应重试,确保埋点不丢失
|
|
11
12
|
- 🎯 精准控制:曝光埋点支持可见比例、单次触发配置
|
|
12
13
|
- ⚡ 轻量无依赖:体积小,不引入额外冗余依赖
|
|
13
14
|
- 📝 完整 TypeScript 类型:提供完善的类型声明,开发更友好
|
|
@@ -25,7 +26,6 @@ yarn add react-track-hooks
|
|
|
25
26
|
pnpm add react-track-hooks
|
|
26
27
|
```
|
|
27
28
|
|
|
28
|
-
|
|
29
29
|
## 快速开始
|
|
30
30
|
|
|
31
31
|
### 1. 全局配置(项目入口)
|
|
@@ -38,13 +38,19 @@ import { setTrackGlobalConfig, useTrackRetryListener } from 'react-track-hooks';
|
|
|
38
38
|
function App() {
|
|
39
39
|
// 全局埋点配置(只执行一次)
|
|
40
40
|
setTrackGlobalConfig({
|
|
41
|
-
trackUrl: 'https://api.yourdomain.com/track', //
|
|
41
|
+
trackUrl: 'https://api.yourdomain.com/track', // 单条埋点上报接口
|
|
42
|
+
batchTrackUrl: 'https://api.yourdomain.com/track/batch', // 批量埋点上报接口(可选)
|
|
42
43
|
enable: process.env.NODE_ENV === 'production', // 生产环境开启
|
|
44
|
+
enableBatch: true, // 全局开启批量上报
|
|
43
45
|
retryConfig: {
|
|
44
46
|
maxRetryTimes: 5, // 最大重试次数
|
|
45
47
|
initialDelay: 1000, // 初始重试延迟(ms)
|
|
46
48
|
delayMultiplier: 2, // 延迟倍数(指数退避)
|
|
47
49
|
},
|
|
50
|
+
batchConfig: {
|
|
51
|
+
batchSize: 10, // 队列达到10条时触发批量上报
|
|
52
|
+
batchInterval: 5000, // 每5秒触发一次批量上报
|
|
53
|
+
}
|
|
48
54
|
});
|
|
49
55
|
|
|
50
56
|
// 启用失败埋点自动重试监听(全局只执行一次)
|
|
@@ -63,7 +69,13 @@ import { setTrackGlobalConfig, useTrackRetryListener } from 'react-track-hooks';
|
|
|
63
69
|
export const TrackProvider = () => {
|
|
64
70
|
setTrackGlobalConfig({
|
|
65
71
|
trackUrl: 'https://api.yourdomain.com/track',
|
|
72
|
+
batchTrackUrl: 'https://api.yourdomain.com/track/batch',
|
|
66
73
|
enable: process.env.NODE_ENV === 'production',
|
|
74
|
+
enableBatch: true, // 全局开启批量上报
|
|
75
|
+
batchConfig: {
|
|
76
|
+
batchSize: 15,
|
|
77
|
+
batchInterval: 3000
|
|
78
|
+
}
|
|
67
79
|
});
|
|
68
80
|
|
|
69
81
|
useTrackRetryListener();
|
|
@@ -96,7 +108,10 @@ function ButtonComponent() {
|
|
|
96
108
|
const handleClick = useTrackClick(
|
|
97
109
|
'button_click', // 埋点事件名
|
|
98
110
|
{ button_type: 'primary', page: 'home' }, // 基础参数
|
|
99
|
-
{
|
|
111
|
+
{
|
|
112
|
+
enable: true,
|
|
113
|
+
enableBatch: false // 单个埋点关闭批量上报(覆盖全局配置)
|
|
114
|
+
}
|
|
100
115
|
);
|
|
101
116
|
|
|
102
117
|
return (
|
|
@@ -114,12 +129,13 @@ import { useTrackExposure } from 'react-track-hooks';
|
|
|
114
129
|
|
|
115
130
|
function CardComponent() {
|
|
116
131
|
// 初始化曝光埋点(返回 ref 绑定到目标元素)
|
|
117
|
-
const exposureRef = useTrackExposure(
|
|
132
|
+
const exposureRef = useTrackExposure<HTMLDivElement>(
|
|
118
133
|
'card_exposure', // 埋点事件名
|
|
119
134
|
{ card_id: '123456', card_type: 'product' }, // 基础参数
|
|
120
135
|
{
|
|
121
136
|
exposureThreshold: 0.8, // 元素可见比例≥80%时触发
|
|
122
137
|
exposureOnce: true, // 仅触发一次曝光
|
|
138
|
+
enableBatch: true // 启用批量上报
|
|
123
139
|
}
|
|
124
140
|
);
|
|
125
141
|
|
|
@@ -139,7 +155,8 @@ function HomePage() {
|
|
|
139
155
|
// 初始化页面停留埋点(组件挂载时自动监听)
|
|
140
156
|
useTrackPageStay(
|
|
141
157
|
'page_stay', // 埋点事件名
|
|
142
|
-
{ page_path: '/home', platform: 'web' } // 基础参数
|
|
158
|
+
{ page_path: '/home', platform: 'web' }, // 基础参数
|
|
159
|
+
{ enableBatch: true } // 启用批量上报
|
|
143
160
|
);
|
|
144
161
|
|
|
145
162
|
return <div>首页内容</div>;
|
|
@@ -154,7 +171,8 @@ function FormComponent() {
|
|
|
154
171
|
// 初始化自定义埋点
|
|
155
172
|
const triggerCustomTrack = useTrackCustom(
|
|
156
173
|
'form_submit', // 埋点事件名
|
|
157
|
-
{ form_id: 'login_form' } // 基础参数
|
|
174
|
+
{ form_id: 'login_form' }, // 基础参数
|
|
175
|
+
{ enableBatch: true } // 启用批量上报
|
|
158
176
|
);
|
|
159
177
|
|
|
160
178
|
const handleSubmit = () => {
|
|
@@ -172,11 +190,9 @@ import { retryFailedTracks } from 'react-track-hooks';
|
|
|
172
190
|
|
|
173
191
|
function RetryButton() {
|
|
174
192
|
const handleRetry = async () => {
|
|
175
|
-
// 手动触发失败埋点重试(force: true
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
alert('失败埋点重试完成!');
|
|
179
|
-
}
|
|
193
|
+
// 手动触发失败埋点重试(force: true 强制立即重试,忽略指数退避时间)
|
|
194
|
+
await retryFailedTracks(true);
|
|
195
|
+
alert('失败埋点重试流程已执行!');
|
|
180
196
|
};
|
|
181
197
|
|
|
182
198
|
return <button onClick={handleRetry}>重试失败埋点</button>;
|
|
@@ -189,20 +205,30 @@ function RetryButton() {
|
|
|
189
205
|
#### setTrackGlobalConfig(config: TrackGlobalConfig)
|
|
190
206
|
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
|
191
207
|
|------|------|------|--------|------|
|
|
192
|
-
| trackUrl | string | 是 | - |
|
|
208
|
+
| trackUrl | string | 是 | - | 单条埋点上报接口地址 |
|
|
209
|
+
| batchTrackUrl | string | 否 | /api/track/batch | 批量埋点上报接口地址 |
|
|
193
210
|
| enable | boolean | 否 | true | 是否开启埋点 |
|
|
211
|
+
| enableBatch | boolean | 否 | true | 是否开启批量上报 |
|
|
194
212
|
| retryConfig | RetryConfig | 否 | 见下方 | 重试配置 |
|
|
213
|
+
| batchConfig | BatchConfig | 否 | 见下方 | 批量上报配置 |
|
|
195
214
|
|
|
196
215
|
#### RetryConfig 类型
|
|
197
216
|
| 参数 | 类型 | 默认值 | 说明 |
|
|
198
217
|
|------|------|--------|------|
|
|
199
|
-
| maxRetryTimes | number | 3 |
|
|
218
|
+
| maxRetryTimes | number | 3 | 最大重试次数(超过则清理埋点) |
|
|
200
219
|
| initialDelay | number | 1000 | 初始重试延迟(ms) |
|
|
201
|
-
| delayMultiplier | number | 2 |
|
|
220
|
+
| delayMultiplier | number | 2 | 延迟倍数(指数退避算法) |
|
|
221
|
+
|
|
222
|
+
#### BatchConfig 类型
|
|
223
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
224
|
+
|------|------|--------|------|
|
|
225
|
+
| batchSize | number | 10 | 触发批量上报的队列容量上限 |
|
|
226
|
+
| batchInterval | number | 5000 | 触发批量上报的时间间隔(ms) |
|
|
202
227
|
|
|
203
228
|
### Hooks
|
|
204
229
|
#### useTrackRetryListener()
|
|
205
|
-
-
|
|
230
|
+
- 作用:全局监听页面状态(初始化/切回标签页/浏览器空闲),自动触发失败埋点重试
|
|
231
|
+
- 特性:内置防并发机制,避免重复执行重试流程
|
|
206
232
|
- 注意:全局只需调用一次,建议放在项目入口
|
|
207
233
|
|
|
208
234
|
#### useTrackClick(eventName, baseParams?, config?)
|
|
@@ -210,64 +236,126 @@ function RetryButton() {
|
|
|
210
236
|
|------|------|------|------|
|
|
211
237
|
| eventName | string | 是 | 埋点事件名 |
|
|
212
238
|
| baseParams | TrackParams | 否 | 基础业务参数 |
|
|
213
|
-
| config |
|
|
239
|
+
| config | TrackConfig | 否 | 单个埋点配置(可覆盖全局批量/重试配置) |
|
|
214
240
|
| 返回值 | (e?, extraParams?) => void | - | 点击事件处理函数,可追加动态参数 |
|
|
215
241
|
|
|
216
|
-
#### useTrackExposure(eventName, baseParams?, config?)
|
|
242
|
+
#### useTrackExposure<T extends HTMLElement>(eventName, baseParams?, config?)
|
|
243
|
+
通用曝光埋点 Hook,返回泛型 ref,可绑定到任意 DOM 元素,元素进入视口时触发埋点上报。
|
|
244
|
+
|
|
217
245
|
| 参数 | 类型 | 必填 | 说明 |
|
|
218
246
|
|------|------|------|------|
|
|
219
247
|
| eventName | string | 是 | 埋点事件名 |
|
|
220
|
-
| baseParams | TrackParams | 否 |
|
|
221
|
-
| config |
|
|
222
|
-
|
|
|
223
|
-
|
|
224
|
-
#### TrackExposureConfig 类型
|
|
225
|
-
| 参数 | 类型 | 默认值 | 说明 |
|
|
226
|
-
|------|------|--------|------|
|
|
227
|
-
| exposureThreshold | number | 0.5 | 触发曝光的可见比例(0-1) |
|
|
228
|
-
| exposureOnce | boolean | true | 是否仅触发一次曝光 |
|
|
248
|
+
| baseParams | TrackParams | 否 | 基础业务参数,会和曝光自动采集参数合并上报 |
|
|
249
|
+
| config | TrackConfig | 否 | 曝光配置 + 批量/重试配置 |
|
|
250
|
+
| 泛型 T | T extends HTMLElement | 否 | 可选,指定 ref 绑定的 DOM 元素类型(默认 `HTMLElement`) |
|
|
251
|
+
| 返回值 | React.RefObject<T> | - | 需绑定到目标元素的 ref,类型与泛型 T 一致 |
|
|
229
252
|
|
|
230
253
|
#### useTrackPageStay(eventName, baseParams?, config?)
|
|
231
254
|
| 参数 | 类型 | 必填 | 说明 |
|
|
232
255
|
|------|------|------|------|
|
|
233
256
|
| eventName | string | 是 | 埋点事件名 |
|
|
234
257
|
| baseParams | TrackParams | 否 | 基础业务参数 |
|
|
235
|
-
| config |
|
|
258
|
+
| config | TrackConfig | 否 | 单个埋点配置(可覆盖全局批量/重试配置) |
|
|
236
259
|
|
|
237
260
|
#### useTrackCustom(eventName, baseParams?, config?)
|
|
238
261
|
| 参数 | 类型 | 必填 | 说明 |
|
|
239
262
|
|------|------|------|------|
|
|
240
263
|
| eventName | string | 是 | 埋点事件名 |
|
|
241
264
|
| baseParams | TrackParams | 否 | 基础业务参数 |
|
|
242
|
-
| config |
|
|
243
|
-
| 返回值 | (extraParams?) =>
|
|
265
|
+
| config | TrackConfig | 否 | 单个埋点配置(可覆盖全局批量/重试配置) |
|
|
266
|
+
| 返回值 | (extraParams?) => void | - | 手动触发埋点的函数 |
|
|
244
267
|
|
|
245
268
|
### 工具函数
|
|
246
|
-
#### retryFailedTracks(force?: boolean): Promise<
|
|
269
|
+
#### retryFailedTracks(force?: boolean): Promise<void>
|
|
270
|
+
增强型失败埋点重试函数,支持批量/单条自适应重试,内置指数退避算法和防并发机制。
|
|
271
|
+
|
|
247
272
|
| 参数 | 类型 | 默认值 | 说明 |
|
|
248
273
|
|------|------|--------|------|
|
|
249
|
-
| force | boolean | false |
|
|
250
|
-
| 返回值 | Promise<
|
|
274
|
+
| force | boolean | false | 是否强制立即重试(忽略指数退避时间) |
|
|
275
|
+
| 返回值 | Promise<void> | - | 重试流程完成的 Promise |
|
|
251
276
|
|
|
252
277
|
### 通用类型
|
|
253
278
|
#### TrackParams
|
|
254
279
|
```ts
|
|
255
280
|
interface TrackParams {
|
|
281
|
+
eventName: string;
|
|
282
|
+
type: 'click' | 'exposure' | 'page_stay' | 'custom';
|
|
256
283
|
[key: string]: any; // 自定义业务参数
|
|
257
284
|
}
|
|
258
285
|
```
|
|
259
286
|
|
|
260
|
-
####
|
|
287
|
+
#### TrackConfig
|
|
288
|
+
```ts
|
|
289
|
+
interface TrackConfig extends Partial<TrackGlobalConfig> {
|
|
290
|
+
exposureOnce?: boolean; // 曝光埋点仅生效一次(默认 true)
|
|
291
|
+
exposureThreshold?: number; // 曝光埋点触发阈值(0-1,默认 0.5)
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
#### TrackGlobalConfig(完整类型定义)
|
|
261
296
|
```ts
|
|
262
|
-
interface
|
|
263
|
-
|
|
297
|
+
export interface TrackGlobalConfig {
|
|
298
|
+
// 埋点上报接口 URL
|
|
299
|
+
trackUrl: string;
|
|
300
|
+
// 批量上报接口 URL
|
|
301
|
+
batchTrackUrl?: string;
|
|
302
|
+
// 是否开启埋点
|
|
303
|
+
enable?: boolean;
|
|
304
|
+
// 是否开启批量上报
|
|
305
|
+
enableBatch?: boolean
|
|
306
|
+
// 重试配置
|
|
307
|
+
retryConfig?: {
|
|
308
|
+
maxRetryTimes: number;
|
|
309
|
+
initialDelay: number;
|
|
310
|
+
delayMultiplier: number;
|
|
311
|
+
};
|
|
312
|
+
// 批量上报配置
|
|
313
|
+
batchConfig?: {
|
|
314
|
+
batchSize: number, // 队列容量上限
|
|
315
|
+
batchInterval: number, // 触发上报间隔
|
|
316
|
+
}
|
|
264
317
|
}
|
|
265
318
|
```
|
|
266
319
|
|
|
320
|
+
## 核心能力说明
|
|
321
|
+
### 批量上报机制
|
|
322
|
+
1. **入队规则**:开启批量上报后,埋点参数先进入内存队列,而非直接发送请求
|
|
323
|
+
2. **触发条件**:满足以下任一条件即触发批量上报:
|
|
324
|
+
- 队列长度达到 `batchSize`(默认 10)
|
|
325
|
+
- 距离上次上报超过 `batchInterval`(默认 5000ms)
|
|
326
|
+
3. **异常处理**:批量上报失败时,所有埋点会自动转入失败队列,参与重试逻辑
|
|
327
|
+
4. **优先级**:单个埋点配置的 `enableBatch` 优先级高于全局配置
|
|
328
|
+
|
|
329
|
+
### 增强型失败重试机制
|
|
330
|
+
#### 核心流程
|
|
331
|
+
1. **失败存储**:上报失败的埋点会存入 localStorage,避免页面刷新丢失
|
|
332
|
+
2. **前置清理**:重试前自动清理超过 `maxRetryTimes` 的过期埋点,避免内存膨胀
|
|
333
|
+
3. **智能筛选**:基于**指数退避算法**筛选可重试埋点:
|
|
334
|
+
```
|
|
335
|
+
重试延迟时间 = initialDelay * (delayMultiplier ^ 当前重试次数)
|
|
336
|
+
```
|
|
337
|
+
例如:初始延迟 1s,倍数 2 → 第1次重试延迟 1s,第2次 2s,第3次 4s...
|
|
338
|
+
4. **自适应重试**:
|
|
339
|
+
- 开启批量时:调用 `batchTrackUrl` 一次性重试所有符合条件的埋点
|
|
340
|
+
- 关闭批量时:逐条调用 `trackUrl` 重试,失败单条不影响其他
|
|
341
|
+
5. **状态更新**:
|
|
342
|
+
- 重试成功:从失败队列移除对应埋点
|
|
343
|
+
- 重试失败:自动更新 `retryCount` 和 `retryTime`,等待下次重试
|
|
344
|
+
6. **重试时机**:
|
|
345
|
+
- 首屏渲染 3 秒后自动重试
|
|
346
|
+
- 页面从不可见变为可见时重试
|
|
347
|
+
- 浏览器空闲时周期性重试(最迟 30 秒一次)
|
|
348
|
+
- 埋点上报成功后自动触发重试
|
|
349
|
+
- 可通过 `retryFailedTracks` 手动触发
|
|
350
|
+
|
|
351
|
+
#### 防并发保护
|
|
352
|
+
- 内置 `isRetryRunning` 状态标记,避免同时执行多个重试流程
|
|
353
|
+
- 所有异常被统一捕获,确保 `isRetryRunning` 能正常重置
|
|
354
|
+
|
|
267
355
|
## 适配说明
|
|
268
356
|
- React 版本:支持 React 16.8+(Hooks 最低兼容版本)
|
|
269
357
|
- Next.js 版本:支持 Next.js 13+(App Router/Pages Router)
|
|
270
|
-
- 浏览器兼容:支持所有现代浏览器,IE 需自行兼容 Promise/IntersectionObserver
|
|
358
|
+
- 浏览器兼容:支持所有现代浏览器,IE 需自行兼容 Promise/IntersectionObserver/requestIdleCallback
|
|
271
359
|
|
|
272
360
|
## 常见问题
|
|
273
361
|
### Q1: TS7016 类型声明找不到?
|
|
@@ -281,10 +369,26 @@ declare module 'react-track-hooks';
|
|
|
281
369
|
A: 检查:
|
|
282
370
|
1. 元素是否绑定 ref;
|
|
283
371
|
2. 可见比例是否达到 `exposureThreshold`;
|
|
284
|
-
3. 元素是否为固定定位/脱离文档流(需确保 IntersectionObserver
|
|
372
|
+
3. 元素是否为固定定位/脱离文档流(需确保 IntersectionObserver 能检测到);
|
|
373
|
+
4. 全局/单个埋点的 `enable` 是否为 `true`。
|
|
285
374
|
|
|
286
|
-
### Q3:
|
|
287
|
-
A:
|
|
375
|
+
### Q3: 批量上报不生效?
|
|
376
|
+
A: 检查:
|
|
377
|
+
1. 全局/单个埋点的 `enableBatch` 是否为 `true`;
|
|
378
|
+
2. `batchTrackUrl` 是否配置正确;
|
|
379
|
+
3. 队列长度是否未达到 `batchSize` 且未到 `batchInterval` 时间。
|
|
380
|
+
|
|
381
|
+
### Q4: 埋点上报失败不重试?
|
|
382
|
+
A: 确保:
|
|
383
|
+
1. 已调用 `useTrackRetryListener()`;
|
|
384
|
+
2. 重试次数未超过 `maxRetryTimes`;
|
|
385
|
+
3. localStorage 未被禁用(失败埋点依赖 localStorage 存储);
|
|
386
|
+
4. 重试时间未到(可通过 `retryFailedTracks(true)` 强制重试验证)。
|
|
387
|
+
|
|
388
|
+
### Q5: 批量重试后部分埋点仍显示失败?
|
|
389
|
+
A: 批量重试为原子操作:
|
|
390
|
+
- 接口返回 2xx → 所有埋点视为成功,从失败队列移除
|
|
391
|
+
- 接口返回非 2xx/网络错误 → 所有埋点视为失败,更新重试次数
|
|
288
392
|
|
|
289
393
|
## 许可证
|
|
290
|
-
MIT © [liujingmin](https://github.com/PassingTraveller111)
|
|
394
|
+
MIT © [liujingmin](https://github.com/PassingTraveller111)
|